英文:
Unsafe pointers, emptyInterface word
问题
我正在尝试理解Go语言中的unsafe.Pointers
内部机制。在结构体中只有一个字段并且返回指向Foo
的指针时,是否有办法始终返回指向Foo
而不是Bar
的指针?只有当*Foo
或Foo
具有多个字段时才起作用。这是编译器优化,还是与堆/栈分配有关?
type Bar struct {
ID int
Name string
Price float64
}
type Foo struct {
Bar *Bar
}
aFoo := Foo{
Bar: &Bar{},
}
// xunsafe.AsPointer 实现:
//
// func AsPointer(v interface{}) unsafe.Pointer {
// empty := (*emptyInterface)(unsafe.Pointer(&v))
// return empty.word
//}
fmt.Printf("Foo ptr: %v, Bar ptr: %v\n", AsPointer(aFoo), unsafe.Pointer(aFoo.Bar))
// 输出: Foo ptr: 0xc00010a060, Bar ptr: 0xc00010a060
编辑:我正在使用go1.17
版本。
英文:
I am trying to understand Go unsafe.Pointers
internal. In case when there is only one field in the struct and returns me a pointer to the Foo
, returns a pointer to the Bar
.
Is there a way to actually return allways pointer to the Foo
not Bar
? It works only when *Foo
or Foo
has more than one field. Is it compiler optimization, or is it related with Heap/Stack allocation?
type Bar struct {
ID int
Name string
Price float64
}
type Foo struct {
Bar *Bar
}
aFoo := Foo{
Bar: &Bar{},
}
//xunsafe.AsPointer implementation:
//
// func AsPointer(v interface{}) unsafe.Pointer {
// empty := (*emptyInterface)(unsafe.Pointer(&v))
// return empty.word
//}
fmt.Printf("Foo ptr: %v, Bar ptr: %v\n", AsPointer(aFoo), unsafe.Pointer(aFoo.Bar))
//Output: Foo ptr: 0xc00010a060, Bar ptr: 0xc00010a060
Edit: I am using the go1.17
.
答案1
得分: 2
使用&aFoo
来获取指向Foo
的指针。
类型unsafe.Pointer
是编译器理解的一种特殊类型。编译器允许在unsafe.Pointer
和其他类型之间进行转换,而这些转换在语言规范中通常是不允许的。
关于xunsafe.Pointer
:你会看到不同的结果,因为这两种类型在存储在接口值中时具有不同的表示形式。
type Foo struct {
Bar *Bar
}
type Foo struct {
Bar *Bar
ASecondField int
}
这是因为这些类型在存储在接口值中时具有不同的表示形式。大于一个字的值被复制到接口值私有的内存中,并且接口值存储指向该内存的指针。xunsafe.AsPointer
函数确实有处理这两种表示形式的代码。
英文:
Use &aFoo
to get a pointer to the Foo
.
The type unsafe.Pointer
is a special type understood by the compiler. The compiler allows conversions between unsafe.Pointer
and other types that are not normally allowed by the language specification.
Regarding xunsafe.Pointer: You see different results for
type Foo struct {
Bar *Bar
}
and
type Foo struct {
Bar *Bar
ASecondField int
}
because those types have different representations when stored in an interface value. Values larger than a word are copied to memory private to the interface value and the interface value stores a pointer to that memory. The xunsafe.AsPointer
function does have code to handle both of representations.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论