pointers - Golang 在另一个结构的方法中更改一个结构的值

标签 pointers go struct slice

如果我的猜测是正确的话,我的结构有问题,指针也可能有问题。

这个结构有一些字段和一个包含 slice 的字段:

type Bot struct {
    // ...
    connlist []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 的更改连接。

有什么想法吗?感谢您的帮助。

最佳答案

你的 ListenToConnection()方法有一个参数:connection Connection .

当您调用此 ListenToConnection() 时方法(你没有发布这段代码),你传递了一个值 Connection . Go 中的所有内容都是按值传递的,因此将对传递的值进行复制。里面ListenToConnection()您使用此副本进行操作。你称它为activateConn()方法,但该方法(具有指针接收器)将接收此副本(局部变量)的地址。

解决方法很简单,更改ListenToConnection()的参数即可成为一个指针:

func (bot *Bot) ListenToConnection(connection *Connection) {
    // ...
}

Bot.connlist 中的值调用它:

bot.ListenToConnection(&bot.connlist[0])

A forconlist 的每个元素循环调用它:

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 中的元素 slice 。

关于pointers - Golang 在另一个结构的方法中更改一个结构的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36517373/

相关文章:

c - 从用户获取字符串并使用 strlen() 查找其长度时出现段错误(核心转储)

c++ - cpp删除旧指针并重新初始化它

go - 访问链接后获取输出字符串

pointers - 如何在 Go 中强制将参数作为指针传递?

c++ - 结构元素的枚举 C++

objective-c - 星号 * 在 Objective-C 中是什么意思?

c - 如何在 C 中查找/打印 hexdump 的偏移量

go - 在 GMail API 中获取附件

c# - 什么时候使用 C# 结构(值类型)会牺牲性能?

go - 如何获取 golang proto 生成的复杂结构中的所有字段名称