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