尝试在Go中更新结构体时,给字段赋值无效。

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

Ineffective Assignment to Field when trying to update a Struct in Go

问题

我遇到了一个代码错误,当我尝试使用结构体方法LevelUp来更新结构体的值Player.Level时,出现了以下的linting错误:

ineffective assignment to field Player.Level (SA4005)go-staticcheck

在调用p.LevelUp()之后,p.Level仍然保持为0。请问如何正确调用一个方法来更新结构体中的字段值?

英文:

I'm getting the linting error

ineffective assignment to field Player.Level (SA4005)go-staticcheck

when I try to use a struct method LevelUp to update the struct's value Player.Level:

func main() {
	player := Player{
		Name:  "Tom",
		Level: 0,
	}
	player.LevelUp()
	fmt.Printf("Player level %d\n", player.Level)
}

type Player struct {
	Name  string
	Level int
}

func (p Player) LevelUp() {
	p.Level += 1  // linting error here
}

p.Level also remains 0 after calling p.LevelUp(). What is the proper way to call a method that updates the value of a field of the struct this method is attached to?

Output:

Player level 0

答案1

得分: 16

每个参数,包括接收器,在进入函数/方法时都会被复制。当你返回时,对副本所做的更改将丢失。这就是为什么你会收到一个警告:你修改了一个你从未使用过的字段:你在赋值后的方法中没有使用它,而且你不可能在其他任何地方使用它,因为从方法返回后,赋值的效果就会丢失。

如果你需要保留更改,你必须使用指针接收器(p *Player)并修改指向的对象(p.Level++就会做到这一点)。

func (p *Player) LevelUp() {
    p.Level++
}

这将输出(在Go Playground上尝试一下):

Player level 1

参考链接:

https://stackoverflow.com/questions/43890706/my-object-is-not-updated-even-if-i-use-the-pointer-to-a-type-to-update-it/43890923#43890923

https://stackoverflow.com/questions/61761945/how-to-modify-the-value-of-a-simple-type-through-pointer-receiver-method-in-go/61762145#61762145

https://stackoverflow.com/questions/42274235/why-cant-i-append-to-a-slice-thats-the-property-of-a-struct-in-golang/42274357#42274357

英文:

Each parameter including the receiver is copied upon entering the function / method. When you return, the changes made to the copy are lost. That's why you get a warning: you modify a field which you never use: you don't use in in the method after the assignment, and you can't possibly use it anywhere else, because after returning from the method, the effect of the assignment is lost.

If you need to retain the changes, you must use a pointer receiver (p *Player) and modify the pointed object (p.Level++ will do just that).

func (p *Player) LevelUp() {
	p.Level++
}

This will output (try it on the Go Playground):

Player level 1

See related:

https://stackoverflow.com/questions/43890706/my-object-is-not-updated-even-if-i-use-the-pointer-to-a-type-to-update-it/43890923#43890923

https://stackoverflow.com/questions/61761945/how-to-modify-the-value-of-a-simple-type-through-pointer-receiver-method-in-go/61762145#61762145

https://stackoverflow.com/questions/42274235/why-cant-i-append-to-a-slice-thats-the-property-of-a-struct-in-golang/42274357#42274357

huangapple
  • 本文由 发表于 2022年8月26日 06:20:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/73494229.html
匿名

发表评论

匿名网友

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

确定