给定任何带有interface{}
类型参数的函数如何在不导航函数源代码的情况下知道是否使用&
传递该参数。
例如,如果我有一个给我这种类型签名的函数:
func foo(x interface{}, y int) int
有没有办法弄清楚x是应该通过值还是通过指针传递?
答案 0 :(得分:2)
以下是来自源代码的片段:
// DecodeElement works like Unmarshal except that it takes
// a pointer to the start XML element to decode into v.
// It is useful when a client reads some raw XML tokens itself
// but also wants to defer to Unmarshal for some elements.
func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error {
val := reflect.ValueOf(v)
if val.Kind() != reflect.Ptr {
return errors.New("non-pointer passed to Unmarshal")
}
return d.unmarshal(val.Elem(), start)
}
正在检查val.Kind() != reflect.Ptr
这意味着您必须通过指针,即& v。
它完全取决于编写方法或函数的人,因此interface{}
可以是* ptr或者任何东西,但是你可以使用reflect.ValueOf(v).Kind()
在函数内部检查值是否是指针与否,并相应地进行。
<强> And little bit about empty interface: 强>
指定零方法的接口类型称为空接口:
interface{}
空接口可以包含任何类型的值。 (每种类型至少实现零方法。)
处理未知类型值的代码使用空接口。例如,fmt.Print采用任意数量的interface{}
类型的参数。
另一个有用的讨论:docs
答案 1 :(得分:1)
DecodeElement()
和朋友有一个正式v interface{}
,其类型记录在Unmarshal()
函数documentation中:
Unmarshal解析XML编码的数据并将结果存储在 v指向的值,它必须是任意的struct,slice或 字符串。
所以要从字面上回答你的问题,不,你不知道没有阅读源 - 如果你要传递的值是一个结构本身,你需要间接。如果它已经是指向该结构的指针,那么你就不会。
例如:
type Result struct {
XMLName xml.Name `xml:"Person"`
Name string `xml:"FullName"`
Phone string
Email []Email
Groups []string `xml:"Group>Value"`
Address
}
var (
a Result
b *Result
c string
)
xmlDecoder.DecodeElement(&a, startElement)
xmlDecoder.DecodeElement(&c, startElement)
但
xmlDecoder.DecodeElement(b, startElement)