我想在内置类型(例如Double)中添加一个方法,以便可以使用一个 infix
运算符。这是否可能?
我想在内置类型(例如Double)中添加一个方法,以便可以使用一个 infix
运算符。这是否可能?
是和不是。是的,你可以让它看起来像你已经向double
添加了一个方法。例如:
class MyRichDouble(d: Double) {
def <>(other: Double) = d != other
}
implicit def doubleToSyntax(d: Double) = new MyRichDouble(d)
这段代码将在任何Double
类型的对象中添加之前不可用的<>
运算符。只要doubleToSyntax
方法处于范围内,以便可以无需限定调用它,以下内容将起作用:
3.1415 <> 2.68 // => true
"no"的答案来源于您并没有真正地向Double
类中添加任何内容。相反,您正在创建一种从Double
到新类型的转换,该新类型定义了所需方法。这可以比许多动态语言提供的开放类技术更为强大。它也是完全类型安全的。 :-)doubleToSyntax
)必须绑定在所需扩展方法的范围内才能使用import Predef._
),要么放在特质中并被继承(例如,class MyStuff extends PredefTrait
)。<>
方法并没有与之相关的神奇功能,解析器只是以那种方式接受它。 如果您喜欢,也可以将“常规方法”用作中缀运算符。 例如,Stream
类定义了一个take
方法,它接受一个Int
参数并返回一个新的Stream
。 可以按以下方式使用它: "val str: Stream[Int] = ...
val subStream = str take 5
str take 5
表达式与str.take(5)
完全相同。
这个功能非常有用,可以实现一个执行错误估计的类:
object errorEstimation {
class Estimate(val x: Double, val e: Double) {
def + (that: Estimate) =
new Estimate(this.x + that.x, this.e + that.e)
def - (that: Estimate) =
new Estimate(this.x - that.x, this.e + that.e)
def * (that: Estimate) =
new Estimate(this.x * that.x,
this.x.abs*that.e+that.x.abs*this.e+this.e*that.e)
def / (that: Estimate) =
new Estimate(this.x/that.x,
(this.x.abs*that.e+that.x.abs*this.e)/(that.x.abs*(that.x.abs-that.e)))
def +- (e2: Double) =
new Estimate(x,e+e2)
override def toString =
x + " +- " + e
}
implicit def double2estimate(x: Double): Estimate = new Estimate(x,0)
implicit def int2estimate(x: Int): Estimate = new Estimate(x,0)
def main(args: Array[String]) = {
println(((x: Estimate) => x+2*x+3*x*x)(1 +- 0.1))
// 6.0 +- 0.93
println(((x: Estimate) => (((y: Estimate) => y*y + 2)(x+x)))(1 +- 0.1))
// 6.0 +- 0.84
def poly(x: Estimate) = x+2*x+3/(x*x)
println(poly(3.0 +- 0.1))
// 9.33333 +- 0.3242352
println(poly(30271.3 +- 0.0001))
// 90813.9 +- 0.0003
println(((x: Estimate) => poly(x*x))(3 +- 1.0))
// 27.037 +- 20.931
}
}
implicit class
语法来简化这个过程。 - lmm