我想向内置类型添加一个方法(例如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

答案的“否”部分来自于这样一个事实:您并没有真正向 Double 班级。相反,您正在创建一个转换 Double 到一个新类型,它定义了您想要的方法。这可能是比许多动态语言提供的开放类更强大的技术。它也恰好是完全类型安全的。:-)

您应该注意一些限制:

  • 该技术不允许您 消除 或者 重新定义 现有方法,只需添加新方法
  • 隐式转换方法(在本例中, doubleToSyntax) 绝对必须在所需扩展方法可用的范围内

习惯上,隐式转换要么放置在单例对象中,要么导入(例如 import Predef._)或在特征和遗传内(例如 class MyStuff extends PredefTrait).

稍稍放一边:Scala 中的“中缀运算符”实际上是方法。没有与此相关的魔法 <> 方法允许它是中缀的,解析器只是以这种方式接受它。如果您愿意,您还可以使用“常规方法”作为中缀运算符。例如, 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
  }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top