我非常喜欢许多语言中都可以使用的用 **
表示乘方的语法(例如 Python)。
在不修改 Scala 基本代码的情况下,是否可能将其引入到 Scala 中呢?
以下是我尝试仅使用 Int
的实现:
import scala.math.pow
implicit class PowerInt(i: Int) {
def `**`(n: Int, b: Int): Int = pow(n, b).intValue
}
(请参见IDEone上的失败情况)
我非常喜欢许多语言中都可以使用的用 **
表示乘方的语法(例如 Python)。
在不修改 Scala 基本代码的情况下,是否可能将其引入到 Scala 中呢?
以下是我尝试仅使用 Int
的实现:
import scala.math.pow
implicit class PowerInt(i: Int) {
def `**`(n: Int, b: Int): Int = pow(n, b).intValue
}
(请参见IDEone上的失败情况)
这个答案来得有些晚,但仍然为了其他人的利益,我想指出被接受的回答在 AnyVal 中不必要地扩展了。
原始回答中只需要修复一个小错误。 def **
方法只需要一个参数,即底数已经在构造函数中传递,而不是像原始代码中一样需要两个。修复这个问题并去掉反引号后的结果如下:
import scala.math.pow
implicit class PowerInt(i: Int) {
def ** (b: Int): Int = pow(i, b).intValue
}
在这里查看,它按预期运作。
如果调用的方法未定义,则Scala编译器将把Int
强制转换为PowerInt
。这就是为什么您不需要从AnyVal扩展的原因。
在幕后,Scala会寻找一个隐式类,其构造函数参数类型与被转换对象的类型相同。由于对象只能有一种类型,因此隐式类的构造函数不能有多个参数。此外,如果您定义了两个具有相同构造函数类型的隐式类,请确保它们的函数具有唯一签名,否则Scala将不知道要转换为哪个类,并会抱怨歧义性。
这对我有效:(问题#1 pow在双精度上定义,问题#2扩展任意值)(同时,在方法名称中使用那些反引号是没有意义的吗?)
import scala.math.pow
object RichIntt {
implicit class PowerInt(val i:Double) extends AnyVal {
def ** (exp:Double):Double = pow(i,exp)
}
def main(args:Array[String])
{
println(5**6)
}
}
有一种方法可以使用 Numeric
类型类使解决方案更加通用:
implicit class PowerOp[T: Numeric](value: T) {
import Numeric.Implicits._
import scala.math.pow
def **(power: T): Double = pow(value.toDouble(), power.toDouble())
}
import scala.Math.pow
):object RichInt {
implicit class PowerInt(val base:Double) {
def ** (pow:Double):Double = if (pow==0) 1 else base*(base**(pow-1))
}
def main(args:Array[String]){
println(2.0**3.0) //8.0
println(2.0**0.0) //1.0
}
}
**
和^
都没有正确的优先级(这就是标准库不包含它们的原因)。4*5**3
等同于(4*5)**3
而不是4*(5**3)
。 - kiritsuku>
<
。 - A T