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

时间:2019-05-09 07:34:37

标签: scala

在scala中,以下作品

1 max 2

但以下内容不

1 Math.pow 2

import Math.pow
1 pow 2

你能解释为什么吗?

6 个答案:

答案 0 :(得分:4)

这里发生了几件事。简而言之:

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

在1个最大值为2的情况下,常数1隐式转换为Int(即Int类的实例)。

由于Int类定义了一个名为“ max”的方法,该方法采用单个参数,因此可以使用空格或infix notation。以下都是等效的(在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           

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

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.


问题的关键部分。

Math.pow是一种采用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

这比+少一些令人兴奋,但很明显,它需要2个Double,然后返回Double。即使提供整数作为参数(需要Doubles时),说Math.pow(2,2)的示例仍然有效,因为Ints会自动转换为Double。

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

答案 1 :(得分:3)

方法不相同的签名:

override def max(that: Long): Long

def pow(x$1: Double,x$2: Double): Double

第一个是Int * 的成员,可以在1上调用,而第二个是在Math对象上调用,并且必须具有两个参数。

* 实际上是RichInt的隐式转换,但是从直观的使用角度来看,它涉及到同一件事,因此这种细微差别不会打扰您

答案 2 :(得分:2)

方法:

override def max(that: Int): Int = math.max(self, that)

来自scala.runtime.RichInt类的bc evry Int由以下内容包装:

@inline implicit def intWrapper(x: Int)         = new runtime.RichInt(x)
scala.LowPriorityImplicits

但是RichInt没有任何pow方法。而且您必须指定Math.pow签名:

public static double pow(double a, double b)

并使用2个参数调用它,或使用自己开发的包装器,例如:

object MainClass {

  implicit class IntHelper(i:Int) {
    def pow(p:Int): Double = Math.pow(i, p)
  }

  def main(args: Array[String]): Unit = {
    println(1 pow 2)
  }
}

输出:

1.0

答案 3 :(得分:1)

1.max(2)只是1的语法糖。

由于scala.Int是整数文字,因此可以以这种方式应用为pow定义的所有方法。 不幸的是scala.Int不是scala.math.BigDecimal

的方法

但是您可以在scala.math.BigIntBigInt(1) pow 2 中找到相关的方法。

因此,以下方法将起作用:

if (index > 1)
{
  (coefficient text box) + *x ^ (index) + //Polynomial2
}
 else if (index == 1)
 {
  (coefficient text box) + *x +  //Polynomial 1
 }
 else if (index == 0)
{
  (coefficient text box)  //Polynomial
}

答案 4 :(得分:0)

您使用的max函数来自Int

它的签名是:

def max(that: Int): Int

由于1是一个Int,因此您可以使用前缀符号来调用1 max 2。就是1.max(2)

pow函数来自Math。 它的签名是

def pow(x: Double, y: Double): Double

由于1不是数学,所以不能简单地调用1 pow 2。另一方面,在Int中,没有 no 方法,例如def pow(that: Int): Int

您可以使用的是pow(a,2),这是Math的实现。

答案 5 :(得分:-2)

Scala.Math Documentation表示pow函数接受两个类型为 Double 的参数,并将第一个参数的值提高为第二个参数的幂。

这是pow函数的工作版本:

import Math.pow

val a: Double = 1

pow(a,2) // returns 1.0