英文:
Struct field reverts
问题
我正在玩一下Go语言,但在进行一些测试时发现了一个奇怪的情况。
我在一个结构体中使用方法将一个变量发送到另一个应该改变字段的方法中,但当我在最后检查时,该字段又回到了初始值,这让我感到困惑。
func (this TVManager) sendMessage(message string) {
fmt.Println("5", this.connector)
payload := map[string]string {
"id": "0",
"type": "request",
"uri": "ssap://system.notifications/createToast",
"payload": "{'message': 'This is a message'}"}
this.connector.sendCommand(payload)
fmt.Println("4", this.connector)
}
这是我正在测试的方法,它调用了连接器的sendCommand方法。
func (this MockConnector) sendCommand(payload map[string]string) {
fmt.Println("0", this)
this.last_command = payload
this.value = true
fmt.Println("0", this)
}
在我使用的模拟对象中,它只是改变了这个结构体字段的值。
manager.sendMessage("This is a message")
fmt.Println("1", connector)
assert.Equal(t, expected, connector.last_command, "Command should be equal")
但是当我检查时,它又回到了初始值。我设置了一些打印语句来尝试跟踪这些值,它们按预期更改了值,但然后又恢复了。
1 {false map[]}
5 {false map[]}
0 {false map[]}
0 {true map[uri:ssap://system.notifications/createToast payload:{'message': 'This is a message'} id:0 type:request]}
4 {false map[]}
1 {false map[]}
--- FAIL: TestTVManagerSendsNotificationDownToConnector (0.00s)
这只是我正在学习Go语言时编写的一个小程序,所以我非常感谢任何人能给我提供帮助。
英文:
I'm playing with Go a bit but found this weird situation while doing some tests.
I'm using method in a struct to send a variable to another method that should change a field, but when I check it at the end, the field goes back to the first value, which has me confused.
func (this TVManager) sendMessage(message string) {
fmt.Println("5", this.connector)
payload := map[string]string {
"id": "0",
"type": "request",
"uri": "ssap://system.notifications/createToast",
"payload": "{'message': 'This is a message'}"}
this.connector.sendCommand(payload)
fmt.Println("4", this.connector)
}
This is the method I'm testing, it calls sendCommand of connector.
func (this MockConnector) sendCommand(payload map[string]string) {
fmt.Println("0", this)
this.last_command = payload
this.value = true
fmt.Println("0", this)
}
Which in the mock object I'm using is simply changing the value of this struct fields.
manager.sendMessage("This is a message")
fmt.Println("1", connector)
assert.Equal(t, expected, connector.last_command, "Command should be equal")
But when I check it, it goes back to internal. I set some prints to try an d track the values and they change the values as expected, but then it reverts.
1 {false map[]}
5 {false map[]}
0 {false map[]}
0 {true map[uri:ssap://system.notifications/createToast payload:{'message': 'This is a message'} id:0 type:request]}
4 {false map[]}
1 {false map[]}
--- FAIL: TestTVManagerSendsNotificationDownToConnector (0.00s)
This is just a small program I'm going over to learn some Go, so I appreciate any help anybody could give me.
答案1
得分: 2
你正在通过值传递结构体。只要你不修改结构体,这样做是可以的,但如果你修改了结构体,实际上只是修改了一个副本。为了使其工作,你需要使用指向需要修改的结构体的指针。
不要使用:
func (this MockConnector) sendCommand(payload map[string]string)
而要使用:
func (this *MockConnector) sendCommand(payload map[string]string)
此外,在Go语言中使用this
(或self
)作为接收器名称被认为是不好的做法,因为接收器与其他语言中的this
指针/引用不是同一概念。
另一个最佳实践是,如果给定类型的一个方法需要指针接收器,那么该类型的所有方法都应该有指针接收器。这样无论值是指针还是非指针,方法集都保持一致。
英文:
You are passing the structures by value. This works fine so long as you are not modifying the structure, but if you do modify it you are actually only modifying a copy. To make this work you need to use pointers to the structures you need to modify.
Instead of:
func (this MockConnector) sendCommand(payload map[string]string)
Use:
func (this *MockConnector) sendCommand(payload map[string]string)
Also, it is considered a bad idea to use this
(or self
) as a receiver name in Go, as a receiver is not the same thing as a this
pointer/reference in other languages.
Another best practice, is if one method for a given type needs a pointer receiver, all methods for that type should have pointer receivers. This is so that the method set remains consistent no matter if the value is a pointer or not.
See method sets, and these FAQ answers for more information.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论