Scala:

2010-01-02 16 views
33

Aşağıdaki örnek, aşırı yöntem \ operatör Kitabın Scala Programlama 'dan. Bir sınıf Verilen 'Akılcı' ve aşağıdaki yöntem tanımı:Scala:

def add(that: Rational): Rational = 
    new Rational(
     this.numer * that.denom + that.numer * this.denom, 
     this.denom * that.denom 
    ) 

Ben başarıyla Int argüman alır kolaylık sürümüyle eklenti yöntemini aşırı yüklenmesine neden olabilecek ve yukarıdaki tanım kullanır:

def add(that: Int): Rational = 
    add(new Rational(that, 1)) 

Şimdiye kadar sorun yok.

Şimdi, bir operatör tarzı ismine yöntem adını değiştirirseniz: şöyle

def +(that: Rational): Rational = 
    new Rational(
     this.numer * that.denom + that.numer * this.denom, 
     this.denom * that.denom 
    ) 

Ve aşırı yük:

(fragment of Rational.scala):19: error: value unary_+ is not a member of this.Rational 
+(new Rational(that, 1)) 
^ 
:

def +(that: Int): Rational = 
    +(new Rational(that, 1)) 

aşağıdaki derleme hatası alıyorum

Derleyici neden + yönteminin tekil bir sürümünü arıyor? Scala

cevap

50

, tip +x, -x, ~x ve !x herhangi yapı Bu mantıksal b olumsuzlaması olarak !b sahip Java benzeri sözdizimi izin vermek için kısmen, vb bir yöntem çağrısı x.unary_+ dönüştürülmüştür, ya da -x, x numaralı telefon numarasının reddedilmesiyle.

nedenle, kod parçacığı +(new Rational(that, 1))(new Rational(that,1)).unary_+ çevrilir ve Rational bu yöntemi bulunmadığından, bir derleme hatası alıyorum. Eğer işlevi bu kadar +, -, ~ veya ! denilen Scala olarak tekli operatörler tanıyan tek karakterlerdir yalnızca bu hatayı alırsınız. Örneğin, işlevinizi @+ olarak adlandırdıysanız, kod yalnızca iyi derlenir.

olsa, ben geçersiz kılınan eklenti fonksiyonu yazma öneririm: Bu kod daha iyi fonksiyon bir eğilimi gösterdiğinden

def +(that: Int): Rational = 
    this + (new Rational(that, 1)) 

- Yeni bir numaratör olarak bir tamsayı inşa Rational ve 1 payda olarak eklemek this. Bu şekilde yazma işlemi this.+(new Rational(that, 1))'a çevrilir, bu da istediğiniz gibi olur - işlevini . Eğer fonksiyon denir ancak infix notasyonu kullanabilirsiniz

Not. Örneğin, geri add adını değiştirirseniz, yine de tanımını tutabilir: Sen ikili + operatörünü belirtmediniz

def add(that: Int): Rational = 
    this add (new Rational(that, 1)) 
3

, sen tekli + operatörü belirttiniz.

Bunu yerine:

def +(that: Int): Rational = 
    +(new Rational(that, 1)) 

Sen bunu yazmak gerekir: Eğer açık this ile + ararsanız

def +(that: Int): Rational = 
    this +(new Rational(that, 1)) 
5

, bu

def +(that: Int): Rational = this.+(new Rational(that, 1)) 

Scala çalışmalıdır tanımlamanızı sağlar önek operatörü notasyonunda kullanılabilen tekli operatörler. Örneğin aynı ulaşmak için bir önek operatörü olarak + kullanabilirsiniz:

def unary_+: Rational = this.+(new Rational(that, 1)) 
val a = new Rational(3,2) 
val b = +a 

açık this olmadan sizin örnekte, derleyici size tanımlanmamıştır tekli operatörü + kullanmakta olduğunu düşünür.