2013-04-11 4 views
3

Go는 동적 바인딩과 정적 바인딩을 모두 사용합니다. 필자가 이해할 때, 타입 어썰트를 사용해야한다면 동적 인 것입니다. 내 가정을 검증하고 싶습니다.Go 인터페이스 : 정적 대 동적 바인딩

type Xer interface { 
    X() 
} 

type XYer interface { 
    Xer 
    Y() 
} 

type Foo struct{} 
func (Foo) X() { println("Foo#X()") } 
func (Foo) Y() { println("Foo#Y()") } 

가정 : type A에서 변환 할 때

foo := Foo{} 

// static: Foo -> XYer 
var xy XYer = foo 

// static: XYer -> Xer 
var x Xer = xy 

// static: Xer -> interface{} 
var empty interface{} = x 

// dynamic: interface{} -> XYer 
xy2 := empty.(XYer) 

// dynamic: XYer -> Foo 
foo2 := xy2.(Foo) 

그래서 - A 만족 B 경우>interface B 다음 주장을 필요로하지 않으며 itable이 컴파일시에 생성 할 수 있습니다. 필요하지 않은 어설 션을 사용하는 경우는 무엇입니까?

var x Xer = Foo{} 
empty := x.(interface{}) 

이 경우 어떻게됩니까? 누군가가 나를 위해 이것을 분명히 할 수 있다면 그것은 위대 할 것이다.

+0

출력하는 어셈블리를 보지 않는 이유는 무엇입니까? – cthom06

+1

@ cthom06 왜냐하면 나는 너무 바보 야. –

+1

[참고] (http://research.swtch.com/interfaces). – kostix

답변

5

jnml의 대답을 확장하기 위해 6g은 형식 어설 션을 생성합니다.

0034 (dumb.go:19) MOVQ $type.interface {}+0(SB),(SP) 
0035 (dumb.go:19) LEAQ 8(SP),BX 
0036 (dumb.go:19) MOVQ x+-32(SP),BP 
0037 (dumb.go:19) MOVQ BP,(BX) 
0038 (dumb.go:19) MOVQ x+-24(SP),BP 
0039 (dumb.go:19) MOVQ BP,8(BX) 
0040 (dumb.go:19) CALL ,runtime.assertI2E+0(SB) 
0041 (dumb.go:19) MOVQ 24(SP),BX 
0042 (dumb.go:19) MOVQ BX,empty+-16(SP) 
0043 (dumb.go:19) MOVQ 32(SP),BX 
0044 (dumb.go:19) MOVQ BX,empty+-8(SP) 

interface{}InterfaceType 스택의 제 값로드 라인 (34)에서, 현재 일어나고 있는지 명확히하기 :

empty := x.(interface{}) 

을 위해 확장된다. 35-36 및 37-38 행은 이 x 인 스택에 쌓습니다. 그런 다음 스택은 runtime.assertI2E이 호출되도록 준비되어 있습니다. 은 리턴 값에 기본 유형 및 데이터를 간단하게 할당합니다. 컴파일러는 이 빈 인터페이스에 할당된다는 것을 알고 있으므로 assertI2E에 대한 호출은 Eface (의미없는 인터페이스)에 대한 인터페이스의 약자이므로 메서드 검사가 필요하지 않습니다. 유일한 제한은 assertI2E입니다. 어설 션 된 값은 인터페이스 여야합니다.

그러나, 당신이 x.(Xer)을하고있는 경우는, runtime.assertI2I는 다음 checks 경우 방법이 인터페이스를 구현하는 호출 된 한 것이다.

+0

와우, 이것은 대단한 답변입니다! 고맙습니다! –

5

인터페이스의 정적 바인딩 또는 인터페이스의 동적 바인딩이 무엇인지 알 수 없습니다. 언어 사양에는 그런 용어가 언급되어 있지 않습니다. 컴파일 타임에 타입 검사를하고 런타임에 타입 검사를한다고 가정합시다. 이 가정을 통해 모든 예제가 AFAICS입니다. 간단한 스키마 (관련 언어 스펙 부분의 압축 된 버전)로 요약됩니다.

  • 모든 할당은 컴파일 타임에 유형을 검사합니다.
  • 모든 유형의 어설 션 (.(T))은 런타임에 유형을 검사합니다.

"이 경우 어떻게됩니까?".

즉, 컴파일러는 컴파일 타임에 형식이 알려져 있고 할당이 가능하다는 것을 증명할 수있는 경우를 자유롭게 최적화 할 수 있습니다. 그러나 이것은 다른 의존적 인 구현의 경우가 아니기 때문에 의존 할 수없는 구현 세부 사항 일뿐입니다.

실제로 gc 컴파일러에는 (IINM) 최적화가 있으며 반대의 의미로 사용됩니다. 타입 선언이 실패 할 것이라는 것을 컴파일 타임에 증명할 수있는 '불가능 타입 선언'이라고 말할 수 있습니다.

+0

나는 [여기] (http://research.swtch.com/interfaces)에서 읽은 것에서 벗어나고 있었다. 메소드 테이블은 런타임에 생성됩니다. 하지만 (인터페이스 변수에 대한) 할당이 컴파일 타임에 유형을 검사한다면 컴파일 시간에 해당 인터페이스에 대한 테이블을 생성 할 수 있다고 생각했습니다. –

+0

아래쪽의 세 번째 단락 http://www.airs.com/blog/archives/277 –