在scala中,以下作品
1 max 2
但以下内容不
1 Math.pow 2
或
import Math.pow
1 pow 2
你能解释为什么吗?
答案 0 :(得分:4)
这里发生了几件事。简而言之:
在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.BigInt
和BigInt(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)
它的签名是:
def max(that: Int): Int
由于1是一个Int,因此您可以使用前缀符号来调用1 max 2
。就是1.max(2)
。
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