首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 下一代語言共同特性(一):操作符重載在 Groovy、Scala、Clojure 中的實現差異

     編輯:Java 相關知識

操作符重載:解決 Java 歷史痛點

Java 無操作符重載導致 BigDecimal 運算極其冗長:

BigDecimal lhs = op1.add(op2.multiply(BigDecimal.valueOf(2)));
BigDecimal rhs = op1.divide(op1.add(op2.multiply(BigDecimal.valueOf(1.5e2))), RoundingMode.HALF_UP);
BigDecimal result = lhs.divide(rhs);

三大下一代 JVM 語言皆實現操作符重載,但方式各異。

Scala:操作符即方法

Scala 消除操作符與方法區別,操作符只是特殊名稱的方法。* 為合法方法名(故導入用 _ 而非 *)。

複數類別完整實現

final class Complex(val real: Int, val imaginary: Int) {
    require(real != 0 || imaginary != 0)
    def +(operand: Complex) = new Complex(real + operand.real, imaginary + operand.imaginary)
    def +(operand: Int) = new Complex(real + operand, imaginary)
    def -(operand: Complex) = new Complex(real - operand.real, imaginary - operand.imaginary)
    def -(operand: Int) = new Complex(real - operand, imaginary)
    def *(operand: Complex) = new Complex(
        real * operand.real - imaginary * operand.imaginary,
        real * operand.imaginary + imaginary * operand.real)
    override def toString() = real + (if (imaginary < 0) "" else "+") + imaginary + "i"
    override def equals(that: Any) = that match {
        case other: Complex => (real == other.real) && (imaginary == other.imaginary)
        case _ => false
    }
    override def hashCode(): Int = 41 * ((41 + real) + imaginary)
}

單元測試自然表達:

val c1 = new Complex(1, 3)
val c2 = new Complex(4, 5)
assert(c1 + c2 === new Complex(5, 8))
assert(c1 * c2 === new Complex(-11, 17))

關聯性規則:以冒號結尾為右結合

Scala 預設左結合:x + y → x.+(y)。方法名以 : 結尾則右結合:i +: j → j.+:(i)。此設計支援開發者最大自由度。

隱式轉換解決混合型別運算

5 + c1 會嘗試呼叫 Int.+() 失敗。解決方案:伴生物件定義隱式轉換:

object Complex {
    implicit def intToComplex(x: Int) = new Complex(x, 0)
}
import Complex.intToComplex

優先級規則:首字元決定

優先級層次(高→低):特殊符號、* / %、+ -、:、= !、< >、&、^、|、字母、賦值操作符。以 = 結尾者最低優先級。

Groovy:映射方法重載

提供可重寫的映射方法:+ → plus()、- → minus()、* → multiply() 等。無法創建新操作符,但引入便利新操作符:?.(安全導航)、?:(Elvis 操作符,三元簡寫)。防止重載新操作符以保護可讀性。

Clojure:符號名稱的方法

操作符只是帶符號名稱的方法(如 +)。正確重載需理解協議與從公共內核生成方法群的技術(下期詳細介紹)。

總結

三語言皆實現操作符重載,簡化 Java 繁瑣限制。Scala 以命名慣例處理關聯性/優先級,Groovy 映射現有操作符並引入新便利操作符,Clojure 以 Lisp 語法(全括號)消除歧義。下期探討「一切皆物件」在三語言中的深層含義。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved