为什么“1 Math.pow 2”在 Scala 中不起作用?

Bun*_*bit 1 scala

在 Scala 中,以下工作

1 max 2

但以下不

1 Math.pow 2

或者

import Math.pow
1 pow 2
Run Code Online (Sandbox Code Playgroud)

你能解释一下为什么吗?

GMc*_*GMc 5

这里有几件事情正在发生。简而言之:

  • 将常量“1”隐式转换为 Int 的实例
  • 为采用单个参数的方法利用“空间符号”

在 1 max 2 的情况下,常量 1 被隐式转换为 Int(即类 Int 的实例)。

由于 Int 类定义了一个名为“max”的方法,它采用单个参数,因此您可以使用空格或中缀表示法。以下都是等效的(在 spark-shell 中运行):

scala> 1 max 2
res8: Int = 2

scala> 1.max(2)
res9: Int = 2

scala> val x = 1     // Note the result type here is Int
x: Int = 1

scala> x.max(2)
res10: Int = 2

scala> x max (2)
res11: Int = 2

scala> 1            // Note the result type here is *also* Int
res12: Int = 1

scala> 1.           // Here are all of the methods that are defined for an Int
!=   +    <<   >>             byteValue     ensuring     formatted    isInfinity      isValidByte    isWhole     notify       signum           toChar        toInt           toString     until   
##   -    <=   >>>            ceil          eq           getClass     isInstanceOf    isValidChar    longValue   notifyAll    synchronized     toDegrees     toLong          unary_+      wait    
%    ->   ==   ^              compare       equals       hashCode     isNaN           isValidInt     max         round        to               toDouble      toOctalString   unary_-      |       
&    /    >    abs            compareTo     floatValue   intValue     isNegInfinity   isValidLong    min         self         toBinaryString   toFloat       toRadians       unary_~      ?       
*    <    >=   asInstanceOf   doubleValue   floor        isInfinite   isPosInfinity   isValidShort   ne          shortValue   toByte           toHexString   toShort         underlying           

Run Code Online (Sandbox Code Playgroud)

请注意,Int 上有很多可用的方法,例如 max、min、+、- 等。查看 say + 的签名,我们可以看到 + 是一个接受单个参数的方法。因此,我们可以执行以下操作:

scala> 1 + 2     // No surprises here
res15: Int = 3

scala> 1.+(2)    // Huh? This works because + is a method of Int that takes a single parameter.
                 // This is effectively the same as your max example.
res16: Int = 3

scala> 1.+       // Here are the signatures of the + method.
   def +(x: Char): Int
   def +(x: Long): Long
   def +(x: Float): Float
   def +(x: Short): Int
   def +(x: Double): Double
   def +(x: Byte): Int
   def +(x: String): String
   def +(x: Int): Int

scala> 1 + 'A'   // From the above, we can see that the following is also valid
res17: Int = 66  // because the return type is Int

scala> 1 + "41"
res18: String = 141   // In this case, the + operator is a String concatenation operator Because the return type is String

scala> 1 + "x"
res19: String = 1x    // Also because the return is String, but possible more intuitive.


Run Code Online (Sandbox Code Playgroud)

问题的战俘部分。

Math.pow 是一种接受 2 个参数的方法。因为它需要 2 个参数,所以您无法使用空格符号。此外,pow 不是与 Int 关联的方法。它很像 Math 类的静态方法(实际上 Math 是一个对象)。所以,就像你不能说 x.pow(y,z) 你不能说 1.pow(y, z) 另一方面你可以说 Math.pow(x, 2) - 得到 x 平方 -因为这与 pow 方法的签名相匹配。

这是 Math.pow 的签名:

scala> Math.pow
   def pow(x$1: Double,x$2: Double): Double
Run Code Online (Sandbox Code Playgroud)

这比 + 少一些令人兴奋,但很明显它需要 2 个 Double 并返回一个 Double。即使整数作为参数提供(当需要双精度时),例如 Math.pow(2,2) 的示例也能工作,因为整数会自动转换为双精度。

我希望这有助于解释你所看到的。我鼓励您在 spark-shell、sbt 或其他一些 Scala REPL 中尝试这些示例。