2 回答
TA贡献1821条经验 获得超4个赞
两种结构的零值不同,这可能是一个显着的人体工程学差异。
考虑嵌入类型
type B struct {
X int
}
func (b *B) Print() { fmt.Printf("%d\n", b.X) }
如果我们直接将其嵌入为对象
type AObj struct {
B
}
那么 type 的零值AObj包括类型 的嵌入对象B,该对象也有其零值,因此我们可以安全地
var aObj AObj
aObj.Print() // prints 0
但如果我们嵌入一个指针
type APtr struct {
*B
}
这个结构体的零值有一个 nil 指针值,我们不能真正直接使用它。
var aPtr APtr
aPtr.Print() // panics
对象有望以您期望的方式被复制。如果您创建一个新AObj对象,它将获得嵌入的B.
aObj2 := aObj
aObj.X = 1
aObj2.Print() // prints 0, because it has a copy
如果创建一个新APtr对象,它会获得 的副本*B,这意味着它共享底层的具体对象。
aPtr.B = &B{}
aPtr2 := aPtr
aPtr.X = 1
aPtr2.Print() // prints 1, because both objects point at the same B
可运行示例位于https://play.golang.org/p/XmOgegwVFeE
TA贡献1824条经验 获得超5个赞
考虑一个简单的示例程序。AstructAPtr嵌入一个指针,a直接structAVal嵌入一个结构体:structB
package main
import "fmt"
type structB struct {
foo int
}
type structAPtr struct {
bar *structB
}
type structAVal struct {
bar structB
}
func main() {
// referencing bStruct
b1 := structB{foo: 12}
aPtr := structAPtr{bar: &b1}
fmt.Println("Before assignment:")
fmt.Printf("aPtr.bar.foo = %d, b.foo = %d\n", aPtr.bar.foo, b1.foo)
aPtr.bar.foo = 42
fmt.Println("After assignment:")
fmt.Printf("aPtr.bar.foo = %d, b.foo = %d\n", aPtr.bar.foo, b1.foo)
// copying bStruct
b2 := structB{foo: 12}
aVal := structAVal{bar: b2}
fmt.Println("Before assignment:")
fmt.Printf("aVal.bar.foo = %d, b.foo = %d\n", aVal.bar.foo, b2.foo)
aVal.bar.foo = 42
fmt.Println("After assignment:")
fmt.Printf("aVal.bar.foo = %d, b.foo = %d\n", aVal.bar.foo, b2.foo)
}
intstructB.foo用于演示在orstructB内部进行操作时是否会发生变化。structAPtrstructAVal
该程序输出:
Before assignment:
aPtr.bar.foo = 12, b.foo = 12
After assignment:
aPtr.bar.foo = 42, b.foo = 42 <------------ both changed
Before assignment:
aVal.bar.foo = 12, b.foo = 12
After assignment:
aVal.bar.foo = 42, b.foo = 12 <------------ only assignee changed
查看结果显示:
改变指针的值来
structB
改变structB
更改复制版本
structB
的值不受影响(它仍然是,即使在被分配给之后)structAVal
structB
5
42
aVal
编辑:
无论如何,如果您structB
只有指针接收器,则预期的行为可能是更改structB
更新strucA
的两个接收器。这是我的示例中的场景 1,并且肯定需要一个指针。来自围棋之旅:
具有指针接收器的方法可以修改接收器指向的值[...]。由于方法通常需要修改其接收器,因此指针接收器比值接收器更常见。
- 2 回答
- 0 关注
- 208 浏览
添加回答
举报