您的匿名结构类型的字段未导出。这意味着您无法创建该结构的值,也无法为另一个包中的字段指定值。规格:复合文字:
为属于不同包的结构的非导出字段指定元素是错误的。
如果您更改结构定义以导出字段,那么它将起作用,因为所有字段都可以由其他程序包分配(请参见Siu Ching Pong -Asuka Kenji-的答案)。
空结构(也没有字段)也是如此:空结构没有字段,因此没有未导出的字段,因此您可以传递该值。
但是,您可以通过反射使用未经修改的结构(具有未导出的字段)来调用该函数。你可以得到
reflect.Type的的
PrintAnonymous()功能,并且可以使用
Type.In()来获取
reflect.Type它的第一个参数。那就是我们要传递值的匿名结构。您可以使用构造该类型的值
reflect.New()。这将是一个
reflect.Value,包装指向匿名结构零值的指针。抱歉,您的结构值不能包含非零值的字段(由于上述原因)。
它看起来像这样:
v := reflect.ValueOf(somepackage.PrintAnonymous)paramt := v.Type().In(0)v.Call([]reflect.Value{reflect.New(paramt).Elem()})这将打印:
0:
0是的零值
int,和的
""空字符串
string。
有趣的是( 这是一个错误
,请参见下面的链接问题),通过反射,您可以使用自己的匿名结构类型的值(具有匹配的未导出字段),在这种情况下,我们可以使用除0之外的其他值。结构域:
value := struct { i int s string}{ 1, "Hello, world!",}v.Call([]reflect.Value{reflect.ValueOf(value)})高于跑步次数(无需惊慌):
1: Hello, world!
允许这样做的原因是由于编译器中的错误。请参见下面的示例代码:
s := struct{ i int }{2}t := reflect.TypeOf(s)fmt.Printf("Name: %q, PkgPath: %qn", t.Name(), t.PkgPath())fmt.Printf("Name: %q, PkgPath: %qn", t.Field(0).Name, t.Field(0).PkgPath)t2 := reflect.TypeOf(subplay.PrintAnonymous).In(0)fmt.Printf("Name: %q, PkgPath: %qn", t2.Name(), t2.PkgPath())fmt.Printf("Name: %q, PkgPath: %qn", t2.Field(0).Name, t2.Field(0).PkgPath)输出为:
Name: "", PkgPath: ""Name: "i", PkgPath: "main"Name: "", PkgPath: ""Name: "i", PkgPath: "main"
如您所见
i,两种匿名结构类型中的未导出字段(在
main包中以及
somepackage作为
PrintAnonymous()函数的参数)–错误地–报告相同的包,因此它们的类型将相等:
fmt.Println(t == t2) // Prints true
注意:我认为这是一个 缺陷
:如果允许使用反射,则应该也可以不使用反射。如果在没有反射的情况下证明了编译时错误,那么使用反射会导致运行时出现恐慌。我为此打开了一个问题,您可以在此处关注它:Issue#16616。Fix当前针对Go1.8。


![以匿名结构作为参数导出函数[在package.Func的参数中不能将值(结构{…}类型)用作结构{…}类型] 以匿名结构作为参数导出函数[在package.Func的参数中不能将值(结构{…}类型)用作结构{…}类型]](http://www.mshxw.com/aiimages/31/452351.png)
