英文:
What's happening with these pointers?
问题
我写了一些奇怪的代码,但我不确定它为什么能工作以及我能从中学到什么。我有一个由另一个结构体构建的切片类型。我在切片类型上创建了一个函数来修改自身。为了做到这一点,我似乎不得不频繁使用 *。
我正在尝试学习Go语言中的指针,并希望得到一点帮助。这里有一个示例(http://play.golang.org/p/roU3MEeT3q):
var ClientNames = []string {"Client A", "Client B", "ClientC"}
type InvoiceSummaries []InvoiceSummary
type InvoiceSummary struct {
Client string
Amt int
}
func (summaries *InvoiceSummaries) BuildFromAbove() {
for _, name := range ClientNames {
*summaries = append(*summaries, InvoiceSummary{name, 100})
}
}
我的问题是:每个 * 的目的是什么,为什么我没有使用任何 &?
英文:
I wrote some odd code, but I'm not sure why it works and what I can learn from it. I have a slice type build from another struct. I made a function on the slice type to modify itself. To do this, I seem to have to throw around *'s a little much.
I'm trying to learn about pointers in Go and would like a little help. Here's an example (http://play.golang.org/p/roU3MEeT3q):
var ClientNames = []string {"Client A", "Client B", "ClientC"}
type InvoiceSummaries []InvoiceSummary
type InvoiceSummary struct {
Client string
Amt int
}
func (summaries *InvoiceSummaries) BuildFromAbove() {
for _, name := range ClientNames {
*summaries = append(*summaries, InvoiceSummary{name, 100})
}
}
My question is: What is the purpose for each of these * and why am I not using any &?
答案1
得分: 1
你必须为接收器使用指针 - (summaries *InvoiceSummaries)
- 因为否则参数是按值传递的,使用指针意味着你传递的是值的引用。如果没有指针,你将无法修改集合。
在方法体内部,你需要使用*
,因为它是解引用运算符,返回地址处的值。而&
则相反,它给出一个值的地址。
英文:
You have to use a pointer for the receiver - (summaries *InvoiceSummaries)
- because otherwise the argument is passed by value, having a pointer means you pass a reference to the value instead. If not for that, then you couldn't modify the collection at all.
Inside of the methods body you have use *
because it is the dereferncing operator and returns the value at the address. Ampersand (&
) is the opposite, it gives the address of a value.
答案2
得分: 1
你的代码没有问题,但通常不会使用地址来引用切片。切片是一个小的结构体,Go语言开发者通常很乐意通过值传递切片。如果一个方法或函数创建了一个新的切片,开发者也很乐意将新的切片再次通过值返回作为返回值。
当然,通过值传递切片并不能保证在方法或函数返回时底层存储保持不变。因此,它不能用作确保切片的数据元素没有发生变化的方法。
英文:
Nothing wrong with your code but normally addresses to slices aren't used. A slice is a small struct that gophers are normally happy to pass by value. If a method or function is creating a new slice, the gopher is happy to return the new slice, by value again, as the return value.
Of course passing a slice by value doesn't guarantee anything about the backing store remaining unchanged when the method/function returns. So it can't be used as a way of guaranteeing the data elements of the slice haven't mutated.
答案3
得分: 1
每个 * 的目的是什么?
通过将方法接收者设为指针,您可以轻松更改对象的属性。我认为这是其中一个好处。下面的示例将证明这一点。
package main
import "fmt"
type someStruct struct {
someVar int
}
func (s someStruct) changeVal1(newVal int) {
s.someVar = newVal
}
func (s *someStruct) changeVal2(newVal int) {
s.someVar = newVal
}
func main() {
s := someStruct{0}
fmt.Println(s) // {0}
s.changeVal1(3)
fmt.Println(s) // {0}
s.changeVal2(4)
fmt.Println(s) // {4}
(&s).changeVal2(5)
fmt.Println(s) // {5}
}
为什么我没有使用任何 &?
指针方法接收者非常特殊,它也可以从非指针结构对象中调用。s.changeVal2(4)
和 (&s).changeVal2(5)
都是有效的,并且会影响 someVar
的值。
示例:http://play.golang.org/p/sxCnCD2D6d
英文:
> What is the purpose for each of these * ?
By making the method receiver as pointer, you could easily change the property of the object. I think that's one of the benefit. This example below will prove it.
package main
import "fmt"
type someStruct struct {
someVar int
}
func (s someStruct) changeVal1(newVal int) {
s.someVar = newVal
}
func (s *someStruct) changeVal2(newVal int) {
s.someVar = newVal
}
func main() {
s := someStruct{0}
fmt.Println(s) // {0}
s.changeVal1(3)
fmt.Println(s) // {0}
s.changeVal2(4)
fmt.Println(s) // {4}
(&s).changeVal2(5)
fmt.Println(s) // {5}
}
> and why am I not using any &?
Pointer method receiver is quite special, it can also be called from non-pointer struct object. Both of s.changeVal2(4)
and (&s).changeVal2(5)
are valid & will affect the value of someVar
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论