Bra*_*ody 5 struct field interface go
使用golang 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) }
}
Run Code Online (Sandbox Code Playgroud)
更改:更改type MyOuterStruct struct { Inner InnerInterface }为完全通用的接口,即使type MyOuterStruct struct { Inner interface{} }其正确呈现。这使我相信interface{}渲染引擎对它进行了特殊处理。
有没有比interface{}我希望能够动态评估像这样的字段更好的方法呢?
您的说法是正确的,interface{}渲染引擎以不同的方式处理这一点。仅interface{}解包值,而不解包具有方法集的接口值。我想这背后的原因是,如果你有一个接口类型,你就专门将该类型限制为方法集。因此,您不希望模板引擎尝试访问可能位于该界面后面的成员。
indirect“问题”是由以下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
}
Run Code Online (Sandbox Code Playgroud)
调用此方法是为了获取反射值的最深值。假设你有一个指针上的指针上的指针,这个函数将返回其中的最后一个。接口值也是如此。关键在于,一旦接口值具有超过 0 个方法,间接寻址就会停止。正是您所描述的行为。
由于这似乎是预期的行为,因此您可以做的是Title() string
在接口中定义一个方法并让它返回字符串。