dongshuo2752 2016-04-09 13:25
浏览 40
已采纳

Golang在另一个结构的方法内更改结构的值

I have an issue with structs and maybe an issue with pointers, if my guess is correct.

This struct has some fields and a field that holds a slice:

type Bot struct {
    // ...
    connlist []Connection
}

This Connection looks like this:

type Connection struct {
    conn       net.Conn
    messages   int32
    channels   []string
    joins      int32
    connactive bool
}

My problem is changing the value of connactive to true.

Bot has a method that listens to the connection:

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
")
        }
        fmt.Fprintf(bot.inconn, line+"
")
    }
}

And connection.activeConn() is the part that is not working correctly the method looks like this:

func (connection *Connection) activateConn() {
    connection.connactive = true
}

This actually gets executed so it's not an issue of the connection not getting a response or something.

But if I try to loop through it later in a method of Bot, connactive is always false for some reason (which is the default).

for i := 0; i < len(bot.connlist); i++ {
        log.Println(bot.connlist[i].connactive)
}

I think I am working with a copy or so of the original connection and not the changed connection that has connactive = true.

Any ideas? Thanks for the help.

  • 写回答

2条回答 默认 最新

  • dongque1462 2016-04-09 13:39
    关注

    Your ListenToConnection() method has one parameter: connection Connection.

    When you call this ListenToConnection() method (you didn't post this code), you pass a value of Connection. Everything in Go is passed by value, so a copy will be made of the passed value. Inside ListenToConnection() you operate with this copy. You call its activateConn() method, but that method (which has a pointer receiver) will receive the address of this copy (a local variable).

    Solution is simple, change parameter of ListenToConnection() to be a pointer:

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

    Calling it with a value from Bot.connlist:

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

    A for loop calling it with every elements of conlist:

    for i := range bot.connlist {
        bot.ListenToConnection(&bot.conlist[i])
    }
    

    Attention! I intentionally used a for ... range which only uses the index and not the value. Using a for ... range with index and value, or just the value, you would observe the same issue (connactive would remain false):

    for _, v := range bot.connlist {
        bot.ListenToConnection(&v) // BAD! v is also a copy
    }
    

    Because v is also just a copy, passing its address to bot.ListenToConnection(), that would only point to the copy and not the element in the connlist slice.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 有没有可以帮我搞一个微信建群链接,包括群名称和群资料群头像那种,不会让你白忙
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题