Go 我不明白什么时候在路上使用指针
我正在参观围棋语言,我有一个关于指针的问题 示例代码: 包干管 进口 fmt 时间 类型MyError结构{ 时间到了,时间到了 什么弦 } func e*MyError错误字符串{ 返回fmt.FAT%v,%s, e、 什么时候,什么 } func运行错误{ 返回和MyError{ 时间到了,现在, 它不起作用, } } func main{ 如果错误:=run;错误!=nil{ 打印错误 } }Go 我不明白什么时候在路上使用指针,go,Go,我正在参观围棋语言,我有一个关于指针的问题 示例代码: 包干管 进口 fmt 时间 类型MyError结构{ 时间到了,时间到了 什么弦 } func e*MyError错误字符串{ 返回fmt.FAT%v,%s, e、 什么时候,什么 } func运行错误{ 返回和MyError{ 时间到了,现在, 它不起作用, } } func main{ 如果错误:=run;错误!=nil{ 打印错误 } } 在本例中,它使用*MyError和&MyError,但我尝试删除*and&并且它工作正常。为什么
在本例中,它使用*MyError和&MyError,但我尝试删除*and&并且它工作正常。为什么他们在这个例子中使用指针?与正态变量有什么区别?什么时候应该使用指针?什么时候应该使用指针?这是一个非常大的问题,没有简单的答案。指针是一种传递对值(而不是值本身)的引用的方法,允许您修改原始值或查看对该值的修改。它还可以防止复制,这在非常有限的情况下可能是一种性能改进。不要一直传递指针,因为这可能是一种性能改进。最后,指针还可以表示虚无,每个指针都可以为零。这既是福也是祸,因为在访问它之前,您必须检查每个指针是否为零 在您的特定示例中,返回&MyError有效的原因是,您的Error函数对指向MyError的指针*MyError的值进行操作,而不是对MyError本身的值进行操作。这意味着*MyError实现了错误接口,因此可以分配给错误类型,因此可以从任何期望错误作为返回值的函数返回 返回MyError本身不起作用,因为MyError不是*MyError。Go在处理函数接收器时做了一些有用的事情:如果接收器是*MyError,它将允许您调用MyError或*MyError上的任何方法,但是如果类型是*MyError,它将只允许您调用*MyError上的方法-也就是说,Go不会凭空为您创建指针 如果您要从func e*MyError中删除*,您将告诉Go该错误适用于MyError的任何实例,这意味着*MyError和MyError都将履行该契约。这就是为什么在不使用指针接收器时,以下两项都有效的原因:
func (e MyError) Error() string {}
var _ error = MyError{} // Valid
var _ error = &MyError {}
在这种特殊情况下,使用指针不会有什么不同。这里有一种方式来看待它: 在Go中,所有变量都按值传递。这意味着:
type T struct {...}
func f(value T) {..}
f(t)
在上面,t作为值传递。这意味着当调用f时,编译器创建t的一个副本并将其传递给f。f对该副本所做的任何修改都不会影响用于调用f的t
如果使用指针:
func f(value *T) {...}
f(&t)
上面,编译器将创建一个指向t的指针,并将该指针的副本传递给f。如果f对值进行更改,则这些更改将在用于调用f的t的实例上进行。换言之:
type T struct {
x int
}
func f(value T) {
value.x=1
}
func main() {
t:=T{}
f(t)
fmt.Println(t.x)
}
这将打印0,因为f所做的修改是在t的副本上完成的
上面,它将打印1,因为对f的调用更改了t
同样的想法也适用于方法和接收器:
type T struct {
x int
}
func (t T) f() {
t.x=1
}
func main() {
t:=T{}
t.f()
fmt.Println(t.x)
}
上面的程序将打印0,因为该方法修改了t的副本
上面的程序将打印1,因为方法的接收器是用指针声明的,调用t.f相当于f&t
因此,如果要修改对象,或者复制对象的成本太高,则在传递参数或声明方法时使用指针
这只是指针参数故事的一小部分
type T struct {
x int
}
func (t T) f() {
t.x=1
}
func main() {
t:=T{}
t.f()
fmt.Println(t.x)
}
func (t *T) f() {
t.x=1
}
func main() {
t:=T{}
t.f()
fmt.Println(t.x)
}