如果我的猜测正确的话,我可能会遇到结构问题,可能还会遇到指针问题。
该结构具有一些字段和一个包含切片的字段:
type Bot struct { // ... connlist []Connection }
这Connection看起来是这样的:
Connection
type Connection struct { conn net.Conn messages int32 channels []string joins int32 connactive bool }
我的问题是将的值更改connactive为true。
connactive
true
Bot 有一个监听连接的方法:
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()是无法正常工作的部分,该方法如下所示:
connection.activeConn()
func (connection *Connection) activateConn() { connection.connactive = true }
这实际上被执行了,所以连接没有得到响应或其他问题不是问题。
但是,如果以后尝试使用的方法来遍历它Bot,connactive则总是false出于某种原因(默认设置)。
false
for i := 0; i < len(bot.connlist); i++ { log.Println(bot.connlist[i].connactive) }
我想我正在使用的是原始连接的副本,而不是原始的连接connactive = true。
connactive = true
有任何想法吗?谢谢您的帮助。
您的ListenToConnection()方法有一个参数:connection Connection。
ListenToConnection()
connection Connection
调用此ListenToConnection()方法时(未发布此代码),您传递了值Connection。Go中的所有内容都是按值传递的,因此将复制所传递的值。在内部ListenToConnection()使用此副本进行操作。您调用其activateConn()方法,但是该方法(具有指针接收器)将接收此副本的地址(局部变量)。
activateConn()
解决方法很简单,将参数更改ListenToConnection()为指针:
func (bot *Bot) ListenToConnection(connection *Connection) { // ... }
用的值调用它Bot.connlist:
Bot.connlist
bot.ListenToConnection(&bot.connlist[0])
一for环带的每一个元素调用它conlist:
for
conlist
for i := range bot.connlist { bot.ListenToConnection(&bot.conlist[i]) }
注意! 我故意使用for ... range仅使用索引而不使用值的a。使用for ... range带索引和值(或仅带值)的with,您将观察到相同的问题(connactive将仍然存在false):
for ... range
for _, v := range bot.connlist { bot.ListenToConnection(&v) // BAD! v is also a copy }
因为v它也是一个副本,将其地址传递给bot.ListenToConnection(),所以它只会指向副本,而不是connlist切片中的元素。
v
bot.ListenToConnection()
connlist