问题的标题几乎总结了一下。我正在使用Go进行反射,并且试图获取reflect.Value()指向的地址。
为什么?
我有一个可以通过两种方式接收结构的函数: 首先..这是结构
type UserInfo struct {
Name string `json:"name"`
Roles *[]model.Role `json:"role"`
UserId int `json:"user_id" db:"id"`
}
一个:
var userInfo types.UserInfo
myFunc(&userInfo)
使用这种方法我很好,因为它是指向已分配内存的结构的指针
第二种方法:
var userInfo *types.UserInfo
myFunc(userInfo)
因此,如果我这样做reflect.Value()
,则为零指针。
我想分配该结构并将userInfo指向新的地方。
现在,如果我也粘贴&userInfo,我可以轻松地做到这一点
并执行:
myFunc(dst interface{}, dstAddr interface{})
{
v := reflect.ValueOf(dstAddr)
t := reflect.TypeOf(dst)
ptr := reflect.New(t.Type())
...
v.Elem().Set(ptr)
}
现在,除了reflect.ValueOf(dst).Addr()
与reflect.ValueOf(&dst)
相同外,实际上reflect.ValueOf(dst).CanAddr()
返回false。
所以..有一种方法可以只拥有reflect.ValueOf(&dst)
而获得reflect.ValueOf(dst)
吗?
答案 0 :(得分:2)
无论您传递给reflect.ValueOf()
或任何其他函数,都将进行复制。
话虽这么说,reflect.Value(foo)
可能无法将原始foo
的地址退还给您,而只能将您的副本地址退还给您。为避免进一步的混乱,在这种情况下,Value.CanAddr()
将返回false
,让您知道可以使用Value.Addr()
返回 的地址并不是大多数人期望的,这不是一个有用的地址。
如前所述,您想传递一个单个值,因此传递&foo
。这样做,您将能够使用Value.Elem()
获得foo
所指向的&foo
值。
还要注意,foo
所获得的(包装的)Value.Elem()
值将是可寻址的,因为它是从reflect.Value
包装&foo
获得的。因此,如果reflect.Value
不是(不是 reflect.ValueOf(foo)
,而是reflect.ValueOf(&foo).Elem()
,则可以返回&foo
。
请参见以下示例:
func main() {
var foo = 3
fmt.Println("Address:", &foo)
bar(&foo)
fmt.Println("After:", foo)
}
func bar(x interface{}) {
v := reflect.ValueOf(x)
v2 := v.Elem()
fmt.Println("Passed pointed value:", v2.Interface())
v2.Set(reflect.ValueOf(4))
fmt.Println("Address got from pointed value:", v2.Addr())
}
这将输出(在Go Playground上尝试):
Address: 0xc000080010
Passed pointed value: 3
Address got from pointed value: 0xc000080010
After: 4