我无法修改这个结构体I,我不明白为什么。

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

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 '&'

huangapple
  • 本文由 发表于 2017年8月4日 23:40:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/45510787.html
匿名

发表评论

匿名网友

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

确定