在Go语言中无法通过引用修改对象。

huangapple go评论115阅读模式
英文:

Cannot modify object by reference in golang

问题

为什么我无法在golang中通过引用传递对象?我99%确定我是将对象通过引用传递给函数,而不是复制对象。我刚开始学习go语言,我总是喜欢在创建真正的代码之前做这样的练习。

无论如何,我的问题是为什么最后一行打印出"Doggy"?我期望最后一行打印出name of dog after: changed name!

代码

  1. package main
  2. import "fmt"
  3. // 基本类型
  4. type Animal struct {
  5. Name string
  6. Age int
  7. }
  8. type Dog struct {
  9. Animal
  10. PropertyFoo1 int // 一些特定于狗的字段
  11. }
  12. func modifyAnimalName(animal *Animal) {
  13. (*animal).Name = "changed name!"
  14. }
  15. func main() {
  16. // 创建一个新的狗
  17. dog := Dog{
  18. Animal: Animal{
  19. Name: "Doggy",
  20. Age: 5,
  21. },
  22. }
  23. var animal Animal = dog.Animal
  24. // 调用 modifyAnimalName(&animal) 前后的值
  25. fmt.Printf("name of dog before: %s \n", dog.Name)
  26. modifyAnimalName(&animal) // 修改动物的名字
  27. // 为什么这里打印的是 Doggy?!
  28. fmt.Printf("name of dog after: %s \n", dog.Name)
  29. }

控制台输出:

  1. name of dog before: Doggy
  2. name of dog after: Doggy

编辑

对不起,我问了这个愚蠢的问题,我刚开始学习go语言

@tkausl 谢谢。我刚注意到,由于你的评论,这一行是在复制一个实体对象。

  1. var animal Animal = dog.Animal

因此,我修改了代码如下:

  1. var animal *Animal = &dog.Animal
  2. fmt.Printf("name of dog before: %s \n", dog.Name)
  3. modifyAnimalName(animal)
  4. // 现在它打印出了不同的名字 :)
  5. fmt.Printf("name of dog after: %s \n", dog.Name)
英文:

Why is it that I am not able to pass an object by reference in golang? I am 99% sure I am passing the object by reference to the function instead of copying the object. I am new to go and I always like making exercises like this before creating real code

Anyways my question is why does the last line printing Doggy? I was epecting for the last line to print name of dog after: changed name!

Code

  1. package main
  2. import "fmt"
  3. // base type
  4. type Animal struct {
  5. Name string
  6. Age int
  7. }
  8. type Dog struct {
  9. Animal
  10. PropertyFoo1 int // some field specific to a dog
  11. }
  12. func modifyAnimalName(animal *Animal) {
  13. (*animal).Name = "changed name!"
  14. }
  15. func main() {
  16. // create a new dog
  17. dog := Dog{
  18. Animal: Animal{
  19. Name: "Doggy",
  20. Age: 5,
  21. },
  22. }
  23. var animal Animal = dog.Animal
  24. // before and after values when calling modifyAnimalName(&animal)
  25. fmt.Printf("name of dog before: %s \n", dog.Name)
  26. modifyAnimalName(&animal) // modify animal name
  27. // why does this prints Doggy?!
  28. fmt.Printf("name of dog after: %s \n", dog.Name)
  29. }

console output:

  1. name of dog before: Doggy
  2. name of dog after: Doggy

Edit

Sorry for asking this dumb question I just started learning go

@tkausl thanks. I just noticed thanks to your comment that this line was copying an entity object.

  1. var animal Animal = dog.Animal

As a result I modified the code to:

  1. var animal *Animal = &dog.Animal
  2. fmt.Printf("name of dog before: %s \n", dog.Name)
  3. modifyAnimalName(animal)
  4. // now it prints a different name :)
  5. fmt.Printf("name of dog after: %s \n", dog.Name)

答案1

得分: 1

你没有通过引用传递。以下是问题的两个解决方案。

解决方案1:使用普通函数

  1. package main
  2. import "fmt"
  3. // 基本类型
  4. type Animal struct {
  5. Name string
  6. Age int
  7. }
  8. type Dog struct {
  9. Animal
  10. PropertyFoo1 int // 一些特定于狗的字段
  11. }
  12. func modifyAnimalName(animal *Animal) {
  13. animal.Name = "修改后的名字!"
  14. }
  15. func main() {
  16. // 创建一个新的狗
  17. dog := Dog{
  18. Animal: Animal{
  19. Name: "狗狗",
  20. Age: 5,
  21. },
  22. }
  23. var animal *Animal = &dog.Animal
  24. fmt.Printf("修改前的狗的名字:%s \n", dog.Name)
  25. modifyAnimalName(animal) // 修改动物的名字
  26. fmt.Printf("修改后的狗的名字:%s \n", dog.Name)
  27. }

解决方案2:使用方法

  1. package main
  2. import "fmt"
  3. type Animal struct {
  4. Name string
  5. Age int
  6. }
  7. type Dog struct {
  8. Animal
  9. PropertyFoo1 int // 一些特定于狗的字段
  10. }
  11. func (a *Animal) modifyAnimalName() {
  12. a.Name = "修改后的名字!"
  13. }
  14. func main() {
  15. // 创建一个新的狗
  16. dog := Dog{
  17. Animal: Animal{
  18. Name: "狗狗",
  19. Age: 5,
  20. },
  21. }
  22. var animal *Animal = &dog.Animal
  23. fmt.Printf("修改前的狗的名字:%s \n", dog.Name)
  24. animal.modifyAnimalName()
  25. fmt.Printf("修改后的狗的名字:%s \n", dog.Name)
  26. }
英文:

You are not passing by reference. Here's two solution to the problem.

Solution 1: Using regular function

  1. package main
  2. import "fmt"
  3. // base type
  4. type Animal struct {
  5. Name string
  6. Age int
  7. }
  8. type Dog struct {
  9. Animal
  10. PropertyFoo1 int // some field specific to a dog
  11. }
  12. func modifyAnimalName(animal *Animal) {
  13. animal.Name = "changed name!"
  14. }
  15. func main() {
  16. // create a new dog
  17. dog := Dog{
  18. Animal: Animal{
  19. Name: "Doggy",
  20. Age: 5,
  21. },
  22. }
  23. var animal *Animal = &dog.Animal
  24. fmt.Printf("name of dog before: %s \n", dog.Name)
  25. modifyAnimalName(animal) // modify animal name
  26. fmt.Printf("name of dog after: %s \n", dog.Name)
  27. }

Solution 2: Using method

  1. package main
  2. import "fmt"
  3. type Animal struct {
  4. Name string
  5. Age int
  6. }
  7. type Dog struct {
  8. Animal
  9. PropertyFoo1 int // some field specific to a dog
  10. }
  11. func (a *Animal) modifyAnimalName() {
  12. a.Name = "changed name!"
  13. }
  14. func main() {
  15. // create a new dog
  16. dog := Dog{
  17. Animal: Animal{
  18. Name: "Doggy",
  19. Age: 5,
  20. },
  21. }
  22. var animal *Animal = &dog.Animal
  23. fmt.Printf("name of dog before: %s \n", dog.Name)
  24. animal.modifyAnimalName()
  25. fmt.Printf("name of dog after: %s \n", dog.Name)
  26. }

huangapple
  • 本文由 发表于 2022年4月14日 08:30:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/71865152.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定