代码之家  ›  专栏  ›  技术社区  ›  Tono Nam

无法在golang中通过引用修改对象

  •  1
  • Tono Nam  · 技术社区  · 2 年前

    为什么我不能在golang通过引用传递对象?我99%确定我是通过引用函数传递对象,而不是复制对象。我是新手,我总是喜欢在创建真正的代码之前做这样的练习

    不管怎么说,我的问题是,为什么最后一行打印狗? 我想打印最后一行 name of dog after: changed name!

    密码

    package main
    
    import "fmt"
    
    // base type
    type Animal struct {
        Name string
        Age  int
    }
    
    type Dog struct {
        Animal
        PropertyFoo1 int // some field specific to a dog
    }
    
    func modifyAnimalName(animal *Animal) {
        (*animal).Name = "changed name!"
    }
    
    func main() {
    
        // create a new dog
        dog := Dog{
            Animal: Animal{
                Name: "Doggy",
                Age:  5,
            },
        }
    
        var animal Animal = dog.Animal
    
        // before and after values when calling modifyAnimalName(&animal)
        fmt.Printf("name of dog before: %s \n", dog.Name)
        modifyAnimalName(&animal) // modify animal name
        // why does this prints Doggy?!
        fmt.Printf("name of dog after: %s \n", dog.Name)
    }
    
    
    

    控制台输出:

    name of dog before: Doggy 
    name of dog after: Doggy
    

    编辑

    抱歉问这个愚蠢的问题我刚开始学围棋

    @谢谢。多亏了你的评论,我才注意到这一行是在复制一个实体对象。

    var animal Animal = dog.Animal
    

    因此,我将代码修改为:

        var animal *Animal = &dog.Animal
    
        fmt.Printf("name of dog before: %s \n", dog.Name)
        modifyAnimalName(animal)
        // now it prints a different name :)
        fmt.Printf("name of dog after: %s \n", dog.Name)
    
    1 回复  |  直到 2 年前
        1
  •  1
  •   Sajidur Rahman    2 年前

    你不是通过引用传递的。这个问题有两个解决方案。

    解决方案1:使用正则函数

    package main
    
    import "fmt"
    
    // base type
    type Animal struct {
        Name string
        Age  int
    }
    
    type Dog struct {
        Animal
        PropertyFoo1 int // some field specific to a dog
    }
    
    func modifyAnimalName(animal *Animal) {
        animal.Name = "changed name!"
    }
    
    func main() {
    
        // create a new dog
        dog := Dog{
            Animal: Animal{
                Name: "Doggy",
                Age:  5,
            },
        }
    
        var animal *Animal = &dog.Animal
        fmt.Printf("name of dog before: %s \n", dog.Name)
        modifyAnimalName(animal) // modify animal name
        fmt.Printf("name of dog after: %s \n", dog.Name)
    }
    

    解决方案2:使用方法

    package main
    
    import "fmt"
    
    type Animal struct {
        Name string
        Age  int
    }
    
    type Dog struct {
        Animal
        PropertyFoo1 int // some field specific to a dog
    }
    
    func (a *Animal) modifyAnimalName() {
        a.Name = "changed name!"
    }
    
    func main() {
        // create a new dog
        dog := Dog{Animal: Animal{Name: "Doggy", Age: 5}}
        var animal *Animal = &dog.Animal
        fmt.Printf("name of dog before: %s \n", dog.Name)
        animal.modifyAnimalName()
        fmt.Printf("name of dog after: %s \n", dog.Name)
    }