Golang 在另一个结构的方法中更改结构的值
Posted
技术标签:
【中文标题】Golang 在另一个结构的方法中更改结构的值【英文标题】:Golang changing values of a struct inside a method of another struct 【发布时间】:2016-07-30 18:23:30 【问题描述】:如果我的猜测是正确的,我的结构和指针可能有问题。
这个结构有一些字段和一个保存切片的字段:
type Bot struct
// ...
connlist []Connection
这个Connection
看起来像这样:
type Connection struct
conn net.Conn
messages int32
channels []string
joins int32
connactive bool
我的问题是将connactive
的值更改为true
。
Bot
有一个监听连接的方法:
func (bot *Bot) ListenToConnection(connection Connection)
reader := bufio.NewReader(connection.conn)
tp := textproto.NewReader(reader)
for
line, err := tp.ReadLine()
if err != nil
log.Printf("Error reading from chat connection: %s", err)
break // break loop on errors
if strings.Contains(line, "tmi.twitch.tv 001")
connection.activateConn()
if strings.Contains(line, "PING ")
fmt.Fprintf(connection.conn, "PONG tmi.twitch.tv\r\n")
fmt.Fprintf(bot.inconn, line+"\r\n")
而connection.activeConn()
是无法正常工作的部分,该方法如下所示:
func (connection *Connection) activateConn()
connection.connactive = true
这实际上是被执行的,所以这不是连接没有得到响应之类的问题。
但是如果我稍后尝试在 Bot
的方法中循环遍历它,由于某种原因(这是默认值),connactive
始终是 false
。
for i := 0; i < len(bot.connlist); i++
log.Println(bot.connlist[i].connactive)
我认为我正在使用原始连接的副本左右,而不是具有connactive = true
的更改连接。
有什么想法吗?感谢您的帮助。
【问题讨论】:
【参考方案1】:您的ListenToConnection()
方法有一个参数:connection Connection
。
当您调用此ListenToConnection()
方法(您没有发布此代码)时,您传递了Connection
的值。 Go 中的所有内容都是按值传递的,因此将对传递的值进行复制。在ListenToConnection()
中,您使用此副本进行操作。你调用它的activateConn()
方法,但是那个方法(它有一个指针接收器)将接收这个副本的地址(一个局部变量)。
解决方法很简单,把ListenToConnection()
的参数改成指针:
func (bot *Bot) ListenToConnection(connection *Connection)
// ...
使用来自Bot.connlist
的值调用它:
bot.ListenToConnection(&bot.connlist[0])
for
循环使用conlist
的每个元素调用它:
for i := range bot.connlist
bot.ListenToConnection(&bot.conlist[i])
注意!我故意使用了for ... range
,它只使用索引而不是值。使用带有索引和值的for ... range
或仅使用值,您会观察到相同的问题(connactive
将保持为false
):
for _, v := range bot.connlist
bot.ListenToConnection(&v) // BAD! v is also a copy
因为v
也只是一个副本,将其地址传递给bot.ListenToConnection()
,这只会指向副本而不是connlist
切片中的元素。
【讨论】:
谢谢!这让我更好地理解了指针。并且循环添加非常有用。 bot.ListenToConnection(&bot.connlist[0]) ---对我来说有点难看【参考方案2】:它需要是指向连接的指针切片。 如果这个属性会同时改变,信号量是必要的。
type Bot struct
// ...
conns []*Connection
func (bot *Bot) ListenToConnection(c *Connection)
// code
type Connection struct
conn net.Conn
messages int32
channels []string
joins int32
isActive bool
isActiveLock sync.RWMutex
func (c *Connection) activateConn()
c.isActiveLock.Lock()
defer c.isActiveLock.Unlock()
c.isActive = true
【讨论】:
以上是关于Golang 在另一个结构的方法中更改结构的值的主要内容,如果未能解决你的问题,请参考以下文章