为 Scala 创建`**` 幂运算符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19748805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating `**` power operator for Scala?
提问by A T
I quite like the **syntax for pow, available in many languages (such as Python).
我非常喜欢 , 的**语法pow,可用于多种语言(例如 Python)。
Is it possible to introduce this into Scala, without modifying the Scala 'base' code?
是否可以在不修改 Scala 的“基本”代码的情况下将其引入 Scala?
My attempt at an Intonly one:
我Int唯一的尝试:
import scala.math.pow
implicit class PowerInt(i: Int) {
def `**`(n: Int, b: Int): Int = pow(n, b).intValue
}
(see it failing on IDEone)
(在IDEone上看到它失败)
回答by Swayam
This answer is 2 years late, still for the benefit of others I'd like to point out that the accepted answer unnecessarily extends from AnyVal.
这个答案晚了 2 年,仍然为了其他人的利益,我想指出已接受的答案不必要地从 AnyVal 延伸。
There is just a minor bug that needs to be fixed in the original answer. The def **method needs only one parameter, i.e. the exponent as the base is already passed in the constructor and not two as in the original code. Fixing that and removing the backticks results in:
只有一个小错误需要在原始答案中修复。该def **方法只需要一个参数,即作为基数的指数已经在构造函数中传递,而不是原始代码中的两个参数。解决这个问题并删除反引号会导致:
import scala.math.pow
implicit class PowerInt(i: Int) {
def ** (b: Int): Int = pow(i, b).intValue
}
Which works as expected as seen here.
这如预期所看到的作品在这里。
Scala compiler will cast an Intto a PowerIntonlyif the method that is called on it is undefined. That's why you don't need to extend from AnyVal.
Scala 编译器只有在调用它的方法未定义时才会将 an 转换Int为 a 。这就是您不需要从 AnyVal 扩展的原因。PowerInt
Behind the scenes, Scala looks for an implicit class whose constructor argument type is the same as the type of the object that is cast. Since the object can have only one type, implicit classes cannot have more than one argument in their constructor. Moreover, if you define two implicit classes with the same constructor type, make sure their functions have unique signatures otherwise Scala wouldn't know which class to cast to and will complain about the ambiguity.
在幕后,Scala 寻找一个隐式类,其构造函数参数类型与被转换的对象类型相同。由于对象只能有一种类型,隐式类在其构造函数中不能有多个参数。此外,如果您使用相同的构造函数类型定义两个隐式类,请确保它们的函数具有唯一的签名,否则 Scala 将不知道要强制转换为哪个类并且会抱怨歧义。
回答by Stefan Kunze
this works for me: (problem#1 pow is defined on doubles, problem#2 extending anyval) (also there is no point in having those backticks in the methodname?)
这对我有用:(问题#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)
}
}
回答by Daniel Slapman
There is a way to make the solution a little bit more generic using Numerictypeclass:
有一种方法可以使用Numerictypeclass使解决方案更加通用:
implicit class PowerOp[T: Numeric](value: T) {
import Numeric.Implicits._
import scala.math.pow
def **(power: T): Double = pow(value.toDouble(), power.toDouble())
}
回答by Massimiliano Giunchi
This is my solution using recursion (so I don't need import scala.Math.pow):
这是我使用递归的解决方案(所以我不需要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
}
}

