2013-10-23 1 views
4

골란 사용 html/template (text/template과 동일한 동작). 인터페이스 유형의 멤버가있는 구조체가있는 경우 기본 유형의 멤버에 액세스 할 수 없습니다 (구체적으로 인터페이스 InnerInterface을 구현하는 구조체의 필드에 액세스하려고 시도하지만 구조체가 아닌 InnerInterface 인터페이스 유형을 통해 반환됩니다). 유형). 변경템플릿은 기본 유형으로 인터페이스 유형 인 필드를 평가하지 않습니다.

http://play.golang.org/p/ZH8wSK83oM

package main 

import "fmt" 
import "os" 
import "html/template" 

type InnerInterface interface{ InnerSomeMethod() } 

type MyInnerStruct struct { Title string } 
func (mis MyInnerStruct)InnerSomeMethod() { fmt.Println("Just to show we're satisfying the interface") } 

type MyOuterStruct struct { Inner InnerInterface } 


func main() { 

    fmt.Println("Starting") 


    arg := MyOuterStruct{Inner:MyInnerStruct{Title:"test1"}} 

    err := template.Must(template.New("testtmpl").Parse("{{.Inner.Title}}")).Execute(os.Stdout, arg) 
    if err != nil { panic(err) } 

} 

: 완전히 일반적인 인터페이스 type MyOuterStruct struct { Inner InnerInterface }, 즉 type MyOuterStruct struct { Inner interface{} }는 제대로 렌더링합니다. 이것은 interface{}이 렌더링 엔진에 의해 특별히 처리된다고 믿게합니다.

이렇게 필드를 동적으로 평가할 수있을 때마다 interface{}을 사용하는 것보다 더 좋은 방법이 있습니까?

답변

4

interface{}은 렌더링 엔진에 다르게 처리된다고 말하는 것이 맞습니다. interface{} 값만 압축을 풉니 다. 메소드 세트가있는 인터페이스 값은 그렇지 않습니다. 인터페이스 유형이있는 경우 유형을 메소드 세트로 구체적으로 제한한다는 것이이 논리의 추측이라고 가정합니다. 따라서 템플릿 엔진이 해당 인터페이스 뒤에있을 수있는 멤버에 액세스하지 못하게하려고합니다.

'문제'

indirect in exec.go은 함수에 의해 야기된다

func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { 
    for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() { 
     if v.IsNil() { 
      return v, true 
     } 
     if v.Kind() == reflect.Interface && v.NumMethod() > 0 { 
      break 
     } 
    } 
    return v, false 
} 

이 방법은 반사 값의 깊은 값 얻기 위해 호출된다. 포인터의 포인터에 포인터가 있다고 가정하면이 함수는 마지막으로 을 반환합니다. 인터페이스 값도 마찬가지입니다. 요점은 인터페이스 값에 0 개 이상의 메소드가있는 즉시 거기에서 중지된다는 것입니다. 정확히 동작을 설명합니다.

의도 한 동작 인 것으로 보이므로 인터페이스에서 Title() string 메서드를 정의하고 문자열을 반환하도록 할 수 있습니다.

+0

Tks for this - 내 프로젝트의 구조면에서 Title() 메소드를 인터페이스에 넣지 않아도되지만 요소가 포함됩니다. 템플릿에서 쉽게 액세스 할 필요가있을 때 인터페이스 {} 유형 필드를 사용하여 종료되었습니다. 그것은 완벽하지는 않지만 실행 가능합니다. 그리고 그것은 무슨 일이 일어나고 있는지 분명합니다. –

관련 문제