2008-11-18 55 views

回答

17

是的,没有。是的,你可以像似乎像你已经添加了一个方法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 

的回答“没有”的一部分来自于事实,你是不是真的添加任何内容到Double类。相反,您正在创建一个从Double到一个确定您想要的方法的新类型的转换。这可能是一种比许多动态语言提供的开放类更强大的技术。它也恰好是类型安全的。 :-)

一些限制,你应该知道的:

  • 这种技术并不让你删除重新定义现有的方法,只需要添加新的
  • 隐式转换方法(在这种情况下,doubleToSyntax)绝对必须在范围内才能使用所需的扩展方法

在语意上,隐式c反转或者放置在单例对象中并被导入(例如, import Predef._)或在特征内并继承(例如class MyStuff extends PredefTrait)。略微放在一边:Scala中的“中缀运算符”实际上是方法。与<>方法没有关系,它允许它是中缀,解析器只是简单地接受它。如果你愿意,你也可以使用“常规方法”作为中缀运算符。例如,Stream类定义了一个采用单个Int参数的take方法,并返回一个新的Stream。这可以通过以下方式被使用:

val str: Stream[Int] = ... 
val subStream = str take 5 

str take 5表达是字面上相同str.take(5)

+0

您可以使用'隐class`语法简化这一点了。 – lmm 2015-07-23 14:23:37

1

此功能就派上了用场,以实现一个类执行错误的估计:

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 
    } 
} 
+0

这实际上挺整洁。 :) – 2008-12-16 00:42:01

相关问题