13

我非常喜欢 的**语法pow,它有多种语言(例如 Python)。

是否可以在不修改 Scala“基础”代码的情况下将其引入 Scala?

我的尝试Int只有一个:

import scala.math.pow
implicit class PowerInt(i: Int) {
    def `**`(n: Int, b: Int): Int = pow(n, b).intValue
}

(看到它在IDEone上失败了)

4

4 回答 4

18

这对我有用:(问题#1 pow 是在双打上定义的,问题#2 扩展了 anyval)(在方法名中使用这些反引号也没有意义吗?)

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)
  }

}
于 2013-11-03T01:30:10.967 回答
18

这个答案晚了 2 年,仍然为了其他人的利益,我想指出,接受的答案不必要地从 AnyVal 延伸。

原始答案中只有一个小错误需要修复。该def **方法只需要一个参数,即作为基数的指数已经在构造函数中传递,而不是原始代码中的两个。修复该问题并删除反引号会导致:

import scala.math.pow
implicit class PowerInt(i: Int) {
    def ** (b: Int): Int = pow(i, b).intValue
}

正如这里所见,它按预期工作。

Scala 编译器当调用它的方法未定义时才会将其强制Int转换为 a 。这就是您不需要从 AnyVal 扩展的原因。PowerInt

在幕后,Scala 寻找一个隐式类,它的构造函数参数类型与被强制转换的对象的类型相同。由于对象只能有一种类型,因此隐式类的构造函数中不能有多个参数。此外,如果您使用相同的构造函数类型定义两个隐式类,请确保它们的函数具有唯一的签名,否则 Scala 将不知道要转换到哪个类并会抱怨歧义。

于 2015-10-26T14:56:37.117 回答
3

有一种方法可以使用 typeclass 使解决方案更加通用Numeric

implicit class PowerOp[T: Numeric](value: T) {
    import Numeric.Implicits._
    import scala.math.pow

    def **(power: T): Double = pow(value.toDouble(), power.toDouble())
}
于 2017-04-24T11:45:52.023 回答
0

这是我使用递归的解决方案(所以我不需要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
    }  
}
于 2018-12-10T23:09:49.197 回答