簡體   English   中英

是否可以在Scala中為內置類型添加方法?

[英]Is it possible to add a method to a built-in type in Scala?

我想為內置類型(例如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._ ),要么在traits中繼承並繼承(例如, 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 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM