2010-01-02 8 views
33

다음 예제는 'Programming in Scala'책의 예제입니다. 클래스를 감안할 때 '하여 Rational'다음과 같은 방법 정의 :스칼라 : 메서드 연산자 오버로드

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

나는 성공적으로 지능 인수를 취하는 편의 버전으로 add 메소드를 오버로드 할 수 있으며, 위의 정의를 사용한다 :

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

지금까지 문제가 없습니다.

지금, 나는 운영자 스타일의 이름으로 메소드 이름을 변경하는 경우 : 그래서 같은

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

그리고 과부하 :

(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)) 

나는 다음과 같은 컴파일 오류

컴파일러가 + 메서드의 단항 버전을 찾는 이유는 무엇입니까? 스칼라

답변

50

, 유형 +x, -x, ~x!x 임의의 구조체는이 부울 b의 부정으로 !b를 갖는 자바와 같은 구문을 허용하도록 부분적 등 메소드 호출 x.unary_+으로 변형되거나 숫자 x의 부정으로서 -x.

따라서 코드 조각 +(new Rational(that, 1))(new Rational(that,1)).unary_+으로 변환되고 Rational에는이 방법이 없으므로 컴파일 오류가 발생합니다. 함수가 +, -, ~ 또는 ! 인 경우에만 스칼라가 단항 연산자로 허용하는 문자이기 때문에이 오류가 발생합니다. 예를 들어 함수 @+을 호출하면 코드가 올바르게 컴파일됩니다.

비록, 내가 같이 재정의 추가 기능을 작성하는 제안 :이 코드는 더 나은 기능의 의도를 보여줍니다

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

- 새 분자로 정수로 구성 Rational1 분모로 추가 this. 이 글은 this.+(new Rational(that, 1))으로 번역되었으므로 + 함수를 this에 호출하면됩니다.

함수가 호출되지만 삽입 기호 표기법을 사용할 수 있습니다. 예를 들어, 당신이 다시 add로 이름을 변경하는 경우, 당신은 여전히 ​​같은 정의를 유지할 수 있습니다 : 당신은 이진 + 연산자를 지정하지 않은

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

을, 당신은 단항 + 연산자를 지정했습니다.

그래서 대신 :

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

당신이를 작성할 필요가 : 당신이 명시 적 this+를 호출 할 경우

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

, 그것은

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

스칼라 작동합니다 정의 할 수 있습니다 접두사 연산자 표기법에 사용할 수있는 단항 연산자. 예를 들어 동일한을 달성하기 위해 접두어 연산자로 + 사용할 수 있습니다

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

을 명시 적 this없이 귀하의 예제에서, 컴파일러는 정의되지 않은 단항 연산자 +을 사용하고 있다고 생각합니다.