为什么我的匿名结构字段上的setter方法不起作用?

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

Why is my setter not working on an anonymous struct field?

问题

我正在学习Go语言,以下是一些我无法理解的行为:

package main

import "fmt"

type Message interface {
    SetSender(sender string)
}

type message struct {
    sender string
}

type Join struct {
    message
    Channel string
}

func (m message) SetSender(sender string) {
    m.sender = sender
}

func main() {
    var msg Message
    msg = Join{}
    msg.SetSender("Jim")
    fmt.Printf("%s", msg)
}

这段代码输出 {{} },所以 SetSender 方法似乎没有生效。我怀疑它在某种程度上操作的是 message 的副本,但我无法找出这样的副本是从哪里来的。我尝试将 SetSender 改为操作 *message,但无法通过编译。

Playground: http://play.golang.org/p/yNdnM1bfSG

欢迎提供替代的设计模式建议。我有几种类型的消息(这里只展示了 Join),但它们都有一些共同的字段(这里只展示了 sender)。我希望避免为每种消息类型编写和导出单独的构造函数,所以如果我可以继续导出这些类型本身,那将非常好。

英文:

I'm just learning Go, and here's some behaviour I can't quite get my head around:

package main

import "fmt"

type Message interface {
	SetSender(sender string)
}

type message struct {
	sender string
}

type Join struct {
	message
	Channel string
}

func (m message) SetSender(sender string) {
	m.sender = sender
}

func main() {
	var msg Message
	msg = Join{}
	msg.SetSender("Jim")
	fmt.Printf("%s", msg)
}

This prints {{} }, so the SetSender call doesn't seem to take effect. I suspect that it is somehow operating on a copy of the message, but I can't figure out where such a copy would come from. I tried changing SetSender to operate on *message but that won't compile.

Playground: http://play.golang.org/p/yNdnM1bfSG

Suggestions for alternative design patterns are also welcome. I have several types of messages (only Join is shown here), but they all have some fields in common (only sender is shown here). I'd like to avoid having to write and export a separate constructor for each message type, so it would be great if I can just keep exporting the types themselves.

答案1

得分: 4

你应该使用指向消息的指针,而不是消息本身。

func (m *message) SetSender(sender string) {
    m.sender = sender
}

func main() {
    var msg Message
    msg = new(Join)
    msg.SetSender("Jim")
    fmt.Printf("%s", msg)
}

这将改变结构。对于 message 上的函数会改变对象的副本,而对于指向 message 的指针上的函数会改变对象本身。

http://golangtutorials.blogspot.com/2011/06/methods-on-structs.html

英文:

You should use pointer to message, not a message.

func (m *message) SetSender(sender string) {
    m.sender = sender
}

func main() {
    var msg Message
    msg = new(Join)
    msg.SetSender("Jim")
    fmt.Printf("%s", msg)
}

It will change the structure. Function on message changes copy of the object, function on pointer to message changes the object.

http://golangtutorials.blogspot.com/2011/06/methods-on-structs.html

huangapple
  • 本文由 发表于 2013年10月17日 19:22:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/19425353.html
匿名

发表评论

匿名网友

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

确定