使用模板的反射创建的值时出现意外的故障地址

I want to minimic type testData by reflect, but got unexpected fault address

func TestData(t *testing.T) {
    tpl, err := template.New("ok").Parse("{{.Ok}}")
    if err != nil {
        panic(err)
    }
    buf := bytes.NewBuffer(nil)
    myTyp := reflect.StructOf([]reflect.StructField{
        {Name: "MyFace", Type: reflect.TypeOf((*MyFace)(nil)).Elem(), Index: []int{0}, Anonymous: true},
    })
    myVal := reflect.New(myTyp).Elem()
    myVal.Field(0).Set(reflect.ValueOf(MyFace(&testFace{})))
    err = tpl.Execute(buf, myVal.Interface()) // unexpected fault address
    //err = tpl.Execute(buf, &testDat{MyFace: MyFace(&testFace{})}) // works as expected
    if err != nil {
        panic(err)
    }
    fmt.Println(buf.String())
}

type testData struct {
    MyFace
}
type testFace struct {
}

func (testFace) Ok() string {
    return "All right"
}

type MyFace interface {
    Ok() string
}

ERROR

unexpected fault address 0xc4200e83a0
[signal SIGBUS: bus error code=0x2 addr=0xc4200e83a0 pc=0xc4200e83a0]

goroutine 5 [running]:
runtime.throw(0x13728ac, 0x5)
    /usr/local/Cellar/go/1.9.1/libexec/src/runtime/panic.go:605 +0x95 fp=0xc420058fe8 sp=0xc420058fc8 pc=0x102d235
runtime.sigpanic()
    /usr/local/Cellar/go/1.9.1/libexec/src/runtime/signal_unix.go:364 +0x29d fp=0xc420059038 sp=0xc420058fe8 pc=0x1043c2d
runtime.call32(0xc42007f260, 0xc42000e0a8, 0xc4200e8560, 0x800000018)
    /usr/local/Cellar/go/1.9.1/libexec/src/runtime/asm_amd64.s:509 +0x3b fp=0xc420059068 sp=0xc420059038 pc=0x105a51b
reflect.Value.call(0xc42009ca00, 0xc420048e10, 0x293, 0x1372569, 0x4, 0x155f1b8, 0x0, 0x0, 0x13711a0, 0x1, ...)
    /usr/local/Cellar/go/1.9.1/libexec/src/reflect/value.go:434 +0x906 fp=0xc420059340 sp=0xc420059068 pc=0x10b1c76
reflect.Value.Call(0xc42009ca00, 0xc420048e10, 0x293, 0x155f1b8, 0x0, 0x0, 0x150f5c0, 0xc420064300, 0xc420064300)
    /usr/local/Cellar/go/1.9.1/libexec/src/reflect/value.go:302 +0xa4 fp=0xc4200593a8 sp=0xc420059340 pc=0x10b1254
text/template.(*state).evalCall(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0xc42009ca00, 0xc420048e10, 0x293, 0x150b800, 0xc42007eff0, 0x137307e, ...)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:670 +0x580 fp=0xc4200595e0 sp=0xc4200593a8 pc=0x12b3480
text/template.(*state).evalField(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0x137307e, 0x2, 0x150b800, 0xc42007eff0, 0xc420048d00, 0x1, ...)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:560 +0xd38 fp=0xc420059940 sp=0xc4200595e0 pc=0x12b2d98
text/template.(*state).evalFieldChain(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0xc42009ca00, 0xc420048e10, 0x99, 0x150b800, 0xc42007eff0, 0xc420048cf0, ...)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:528 +0x22a fp=0xc4200599f8 sp=0xc420059940 pc=0x12b1d2a
text/template.(*state).evalFieldNode(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0xc42007eff0, 0xc420048d00, 0x1, 0x1, 0x0, 0x0, ...)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:492 +0x118 fp=0xc420059ab0 sp=0xc4200599f8 pc=0x12b1478
text/template.(*state).evalCommand(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0xc42007efc0, 0x0, 0x0, 0x0, 0x348a0, 0x12fa0e0, ...)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:430 +0x676 fp=0xc420059b60 sp=0xc420059ab0 pc=0x12b0e26
text/template.(*state).evalPipeline(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0xc420088280, 0xc42007f1d0, 0x30, 0x28)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:408 +0x115 fp=0xc420059c58 sp=0xc420059b60 pc=0x12b0315
text/template.(*state).walk(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0x150b620, 0xc42007f020)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:234 +0x4af fp=0xc420059cd8 sp=0xc420059c58 pc=0x12af01f
text/template.(*state).walk(0xc420059dd0, 0xc42009ca00, 0xc420048e10, 0x99, 0x150b920, 0xc42007ef90)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:242 +0x11d fp=0xc420059d58 sp=0xc420059cd8 pc=0x12aec8d
text/template.(*Template).execute(0xc4200107c0, 0x1505a00, 0xc4200fe620, 0xc42009ca00, 0xc420048e10, 0x0, 0x0)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:197 +0x1f9 fp=0xc420059e28 sp=0xc420059d58 pc=0x12ae6c9
text/template.(*Template).Execute(0xc4200107c0, 0x1505a00, 0xc4200fe620, 0xc42009ca00, 0xc420048e10, 0x16, 0x194)
    /usr/local/Cellar/go/1.9.1/libexec/src/text/template/exec.go:180 +0x53 fp=0xc420059e70 sp=0xc420059e28 pc=0x12ae4a3
wenerme/tests/wcwork.TestData(0xc4201020f0)
    /Users/wener/go/src/wenerme/tests/wcwork/types_test.go:241 +0x31f fp=0xc420059fa8 sp=0xc420059e70 pc=0x12c459f
testing.tRunner(0xc4201020f0, 0x1387c28)
    /usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0 fp=0xc420059fd0 sp=0xc420059fa8 pc=0x10efc60
runtime.goexit()
    /usr/local/Cellar/go/1.9.1/libexec/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420059fd8 sp=0xc420059fd0 pc=0x105cd41
created by testing.(*T).Run
    /usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:789 +0x2de

goroutine 1 [chan receive]:
testing.(*T).Run(0xc420102000, 0x13732b1, 0x8, 0x1387c28, 0x107ab01)
    /usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:790 +0x2fc
testing.runTests.func1(0xc420102000)
    /usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:1004 +0x64
testing.tRunner(0xc420102000, 0xc420057de0)
    /usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:746 +0xd0
testing.runTests(0xc4200e8320, 0x153b700, 0x5, 0x5, 0xc42009c820)
    /usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:1002 +0x2d8
testing.(*M).Run(0xc420057f18, 0xc420057f70)
    /usr/local/Cellar/go/1.9.1/libexec/src/testing/testing.go:921 +0x111
main.main()

What's wrong with with reflect ?

you can pass reflect.Value directly into text/template and html/template execute method. If you change your code and pass them directly and use {.MyFace.Ok} everything works fine. I attach my code:

package hello

import (
    "bytes"
    "fmt"
    "html/template"
    "reflect"
    "testing"
)

func TestData(t *testing.T) {
    tpl, err := template.New("ok").Parse("{{.MyFace.Ok}}")
    if err != nil {
        panic(err)
    }
    buf := bytes.NewBuffer(nil)
    myTyp := reflect.StructOf([]reflect.StructField{
        {Name: "MyFace", Type: reflect.TypeOf((*MyFace)(nil)).Elem(), Index: []int{0}, Anonymous: true},
    })
    fmt.Println(myTyp)
    myVal := reflect.New(myTyp)
    myVal.Elem().Field(0).Set(reflect.New(reflect.TypeOf(testFace{})).Elem())
    err = tpl.Execute(buf, myVal.Elem()) // unexpected fault address
    //err = tpl.Execute(buf, &testDat{MyFace: MyFace(&testFace{})}) // works as expected
    if err != nil {
        panic(err)
    }
    fmt.Println(buf.String())
}

type testData struct {
    MyFace
}
type testFace struct {
    i int
}

func (testFace) Ok() string {
    return "All right"
}

type MyFace interface {
    Ok() string
}

but as you can test with use myVal.Elem().Interface() in above code all of your problems because go cannot find Ok method on your passed interface.

As you can see in reflect.StructOf documentation StructOf currently does not generate wrapper methods for embedded fields. This limitation may be lifted in a future version.