2011-06-10 3 views
1

나는 자기가 매우 흥미로운 사실을 발견했다. 예를 들어 내가 쓴했습니다구조 형

type A = { val st: Set[Any] 
      val start: Set[Any] 
      val Sigma : Set[Char] 
      def tr(f: (Tuple2[Any, Any])=>Boolean): Set[Any] 
      } 
class Fon { 
      val st: Set[Any] 
      val start: Set[Any] 
      val Sigma : Set[Char] 
      def tr(f: (Tuple2[Any, Any])=>Boolean): Set[Any] = Set(out) 
      def out: String = "is just example" 
} 
val a: A = new Fon 
a.tr(f(Tuple2('a',0))) 

을하지만 a.out을 부릅니까 시도한다면 - 나는 A 형이 존재하지 않은 것으로, 오류가이 일어나고 것은이 어떻게 일을 무엇 '아웃' ? 감사합니다. .

+3

이 코드는 올바르지 않습니다. 적어도'Set [out]'과'Tuple [ 'a, 0]'은'()'대신'[]'가 사용되기 때문에 올바르지 않습니다. 또한 구조 타입과 관련이 없습니다. - val a : AnyRef = new Fon; a.out' 그것은 모두 동일하게 불평 할 것이다. –

+0

어쩌면 내가 이해할 수 없지만 다음과 같이 할 수 있을까요? type A = {def out : String}; class AA {def out : String = out2; def out2 = "out2"; val a : A = 새로운 AA; a.out' - result'String = out2' – dvigal

+0

@lisasha 예제에는'}'가 없습니다. 나는'out2'의 정의 후에 가정합니다. 어쨌든, 그 질문이나 진술인가? 질문이라면 그렇다. 진술이 있다면, 나는 당신이하려는 요점을 이해하지 못합니다. 그것이 실패 할 것으로 예상 했습니까? 그렇다면 왜? –

답변

5

A 유형을 정의했기 때문에 A.out과 같은 메소드가 없습니다. 따라서 A 유형의 객체에 out이라는 메서드를 호출하려고하면 컴파일러에서 해당 메서드가 존재하지 않는다고 올바르게 알려줍니다.

구조적 타이핑과 관련이 없습니다. A을 특성으로 사용하고 Fon 특성을 확장하면 똑같은 문제가 발생합니다. 게다가 이것은 정적 타이핑 시스템이 작동하는 방식입니다. 컴파일러는 코드가 타입 안전성을 보장 할 수 없으므로 컴파일하지 않습니다.

당신이 out 메소드를 호출 할 경우에, 당신은 Fon 변수를 통해 그 객체를 참조해야합니다 : 기본적으로

val a: Fon = new Fon 
println(a.out) // works fine, since a is guaranteed to be a Fon and thus have the method 
+0

우리가 가질 수있는 모든 유머는 형식적으로 정의 된 유형과 클래스 또는 싱글 톤, 일반적으로 구현을 표현할 객체입니다. 그것은 좋고 좋지 않을 수 있습니다 ... 나는 어떻게 그리고 왜 컴파일러가 이것을 허용 하는지를 궁금해합니다 - 메소드 tr에서 'out'을 사용하고 그 클래스 Fon을 타입 A라고 추론합니다. – dvigal

1

그것이 다른했다 당신이 하나의 객체 (Fon)를 사용할 수 있습니다 (A) 그들은 동일한 기능을 가지고 있습니다.

outA의 기능이 아니기 때문에 컴파일러가 진행할 수 없습니다.

0

유형 A는 추상 클래스 또는 특성입니다. 그것의 멤버 변수와 메소드는 추상적이다.

type A = {val st: Set[Any] 
    val start: Set[Any] 
    val Sigma: Set[Char] 
    def tr(f: (Tuple2[Any, Any]) => Boolean): Set[Any] 
    } 

Fon은 구체적인 클래스이며 모든 추상 멤버를 구현합니다.

class Fon { 
    val st: Set[Any] = null 
    val start: Set[Any] = null 
    val Sigma: Set[Char] = null 

    def tr(f: (Tuple2[Any, Any]) => Boolean): Set[Any] = Set(out) 

    def out: String = "is just example" 
    } 

그래서, 당신은 변수를 정의 할 수 있습니다, 타입 A는, 구체적인 예는 폰어

입니다
val a: A = new Fon 
    println(a.tr(_ => false)) // Set(is just example) 

추가 : f: (Tuple2[Any, Any]) => Boolean 그렇게 매개 변수로 추상적 인 고차 기능, , 경우입니다 메소드 tr을 호출하려는 경우 a.tr(f(Tuple2('a',0))) 호출 모드는 기호 f를 해석 할 수 없습니다. f: (Tuple2[Any, Any]) => Boolean 매개 변수를 가져 와서 부울 값을 반환합니다. 그래서 (_ => false)은 구체적인 구현체입니다.