英文:
I can't mutate this struct I and I don't understand why
问题
考虑以下的代码片段:
package main
import (
"fmt"
)
type StateTransition struct {
msg Message
}
type Message interface {
To() *string
}
type Transaction struct {
data txdata
}
type txdata struct {
Recipient *string
}
func (t Transaction) To() (*string) {
return t.data.Recipient
}
func UnMask(n **string, k string) {
*n = &k
}
func main() {
toField := "Bob"
toPtr := &toField
txd := txdata{toPtr}
tx := Transaction{txd}
st := StateTransition{tx}
n1 := st.msg.To()
fmt.Printf("Hello, %s \n", *n1)
UnMask(&n1, "Joe")
fmt.Printf("Hello, %s \n", *n1)
n2 := st.msg.To()
fmt.Printf("Hello, %s \n", *n2)
}
输出结果
Hello, Bob
Hello, Joe
Hello, Bob
期望输出
Hello, Bob
Hello, Joe
Hello, Joe
结果输出的顺序是"Bob, Joe, Bob",而我的直觉告诉我应该是"Bob, Joe, Joe"(这也是我希望它输出的)。有经验的Go开发者能否解释一下关于指针、结构体和接口的组合在这个问题中的相关知识,以便让我理解为什么我错了,以及如何修复它?
英文:
Consider the following gist linked here:
Code:
package main
import (
"fmt"
)
type StateTransition struct {
msg Message
}
type Message interface {
To() *string
}
type Transaction struct {
data txdata
}
type txdata struct {
Recipient *string
}
func (t Transaction) To() (*string) {
return t.data.Recipient
}
func UnMask(n **string, k string) {
*n = &k
}
func main() {
toField := "Bob"
toPtr := &toField
txd := txdata{toPtr}
tx := Transaction{txd}
st := StateTransition{tx}
n1 := st.msg.To()
fmt.Printf("Hello, %s \n", *n1)
UnMask(&n1, "Joe")
fmt.Printf("Hello, %s \n", *n1)
n2 := st.msg.To()
fmt.Printf("Hello, %s \n", *n2)
}
Output
Hello, Bob
Hello, Joe
Hello, Bob
Expected Output
Hello, Bob
Hello, Joe
Hello, Joe
The result is the sequence "Bob, Joe, Bob" is printed whereas my intuition says that it should be "Bob, Joe, Joe" (this is also what i want it to print). Can someone experienced in go please explain to me enough about combining pointers, structs, and interfaces as they relate to this problem to give me some understanding about why I'm wrong, and how to fix it?
答案1
得分: 1
Unmask函数接受一个指向指针的指针,假设指针X指向指针Y,指针Y指向字符串值。Unmask函数然后更改指针X指向的指针,指针Y保持不变,仍然指向同一个旧字符串。
你可以这样做:
func UnMask(n **string, k string) {
**n = k
}
或者
func UnMask(n *string, k string) {
*n = k
}
// ....
UnMask(n1, "Joe") // 去掉'&'
英文:
Unmask takes a pointer to a pointer, let's say pointer X to pointer Y, pointer Y points to the string value. Unmask then changes the pointer to which X is pointing to, Y is unchanged and points still to the same old string.
You can do this:
func UnMask(n **string, k string) {
**n = k
}
or
func UnMask(n *string, k string) {
*n = k
}
// ....
UnMask(n1, "Joe") // drop the '&'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论