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

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

Cannot modify object by reference in golang

问题

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

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

代码

package main

import "fmt"

// 基本类型
type Animal struct {
	Name string
	Age  int
}

type Dog struct {
	Animal
	PropertyFoo1 int // 一些特定于狗的字段
}

func modifyAnimalName(animal *Animal) {
	(*animal).Name = "changed name!"
}

func main() {

	// 创建一个新的狗
	dog := Dog{
		Animal: Animal{
			Name: "Doggy",
			Age:  5,
		},
	}

	var animal Animal = dog.Animal

	// 调用 modifyAnimalName(&animal) 前后的值
	fmt.Printf("name of dog before: %s \n", dog.Name)
	modifyAnimalName(&animal) // 修改动物的名字
	// 为什么这里打印的是 Doggy?!
	fmt.Printf("name of dog after: %s \n", dog.Name)
}


控制台输出:

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

编辑

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

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

var animal Animal = dog.Animal

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

var animal *Animal = &dog.Animal

fmt.Printf("name of dog before: %s \n", dog.Name)
modifyAnimalName(animal)
// 现在它打印出了不同的名字 :)
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

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)
}


console output:

name of dog before: Doggy 
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.

var animal Animal = dog.Animal

As a result I modified the code to:

	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

得分: 1

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

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

package main

import "fmt"

// 基本类型
type Animal struct {
    Name string
    Age  int
}

type Dog struct {
    Animal
    PropertyFoo1 int // 一些特定于狗的字段
}

func modifyAnimalName(animal *Animal) {
    animal.Name = "修改后的名字!"
}

func main() {
    // 创建一个新的狗
    dog := Dog{
        Animal: Animal{
            Name: "狗狗",
            Age:  5,
        },
    }

    var animal *Animal = &dog.Animal
    fmt.Printf("修改前的狗的名字:%s \n", dog.Name)
    modifyAnimalName(animal) // 修改动物的名字
    fmt.Printf("修改后的狗的名字:%s \n", dog.Name)
}

解决方案2:使用方法

package main

import "fmt"

type Animal struct {
    Name string
    Age  int
}

type Dog struct {
    Animal
    PropertyFoo1 int // 一些特定于狗的字段
}

func (a *Animal) modifyAnimalName() {
    a.Name = "修改后的名字!"
}

func main() {
    // 创建一个新的狗
    dog := Dog{
        Animal: Animal{
            Name: "狗狗",
            Age:  5,
        },
    }
    var animal *Animal = &dog.Animal
    fmt.Printf("修改前的狗的名字:%s \n", dog.Name)
    animal.modifyAnimalName()
    fmt.Printf("修改后的狗的名字:%s \n", dog.Name)
}
英文:

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

Solution 1: Using regular function

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)
}

Solution 2: Using method

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)
}

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:

确定