반환 유형이 명시 적으로 지정되지 않은 경우 String을 반환하는 메서드로 Unit을 반환하는 메서드를 재정의 할 수있는 이유는 무엇입니까?


11

Scala Edition1 https://www.artima.com/pins1ed/traits.html 에서 프로그래밍의 특성에 관한 장의 코드 예제를 작업했습니다.

오타 때문에 이상한 행동을 겪었습니다. 코드 아래의 특성의 메서드를 재정의하는 동안 오버라이드 (override) 된 메소드의 반환 형식이 다르지만 어떤 컴파일 오류를 제공하지 않는 UnitString. 그러나 객체에서 메소드를 호출하면 Unit을 반환하지만 아무것도 인쇄하지 않습니다.

trait Philosophical {
    def philosophize = println("I consume memory, therefore I am!")
}

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize = "It aint easy to be " + toString + "!"
}

val frog = new Frog
//frog: Frog = green

frog.philosophize
// no message printed on console

val f = frog.philosophize
//f: Unit = ()

그러나 재정의 된 메소드에 명시 적 반환 유형을 제공하면 컴파일 오류가 발생합니다.

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize: String = "It aint easy to be " + toString + "!"
}
         override def philosophize: String = "It aint easy to be " + toString +
                      ^
On line 3: error: incompatible type in overriding
       def philosophize: Unit (defined in trait Philosophical);
        found   : => String
        required: => Unit

첫 번째 경우 컴파일 오류가없는 이유를 누구나 설명 할 수 있습니다.


컴파일러는 다른 결과 유형을 가진 메소드를 대체하려고 시도하는 유효한 힌트를 인쇄했습니다.
Andriy Plokhotnyuk

그렇습니다.하지만 제 질문은 왜 컴파일러가 첫 번째 경우에 컴파일러를 통과했는지
Shanil

1
경험상, 항상 반환 유형 _ (특히 공개 API) _에 대해 명시 적입니다. 타입 추론은 지역 변수에 좋습니다.
Luis Miguel Mejía Suárez '12

답변:



6

내 질문은 왜 첫 번째 경우에 컴파일러를 통과했는지입니다.

리턴 유형을 명시 적으로 지정하지 않은 경우 리턴 유형 override이 작동 하는 데 필요한 유형으로 유추되었습니다 .

로 밝혀졌습니다 Unit.

이후 String값 (함수 본체를 구성하는 식의 값)에 할당 할 수있는 Unit컴파일러 행복하다.


1
그러나 지금 알고 싶은 것은 명시적인 반환 유형 String이 거부 된 이유 입니다. Java (그리고 Scala에서도 생각합니다)에서는 재정의 할 때 반환 유형 을 좁힐 수 있습니다. 예를 들어, 상위 메소드가을 리턴 Number하면을 리턴 할 수 있습니다 Integer. 어쩌면 void/ Unit특별하다.
Thilo

1
예를 들면 다음과 같습니다.trait Philosophical { def philosophize : Number = 1 } class Frog extends Philosophical { override def philosophize : Integer = 2 }
Thilo

2
리턴 유형을 하위 유형으로 좁힐 수 있습니다. 그러나 재정의 된 메서드의 반환 형식으로 만 암시 적으로 변환 할 수있는 형식으로 범위를 좁힐 수는 없습니다. String에는 Unit그렇지 않은 경우에도 더 두 번째처럼 정확히 그.
Alexey Romanov

2
바이트 코드 레벨에서는 좁히는 반환 유형이 없으며 실제로 두 가지 방법이 있습니다 Frog: def philosophize : Integerdef philosophize : Number. 두 번째 것은 실제로 Philosophical의 메소드를 대체 하고 첫 번째 메소드를 호출합니다. void다른 것들에 대해서도 똑같이 할 수 있었으며 , 디자이너들은 방금하지 않기로 결정했습니다.
Alexey Romanov

2
1. 자바도 마찬가지입니다. 2. 예, 바이트 코드로 가능합니다. 예를 들어 stackoverflow.com/questions/18655541/…stackoverflow.com/questions/58065680/…을 참조하십시오 .
Alexey Romanov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.