go在方法中修改结构体的值_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\r\n")

}

fmt.Fprintf(bot.inconn, line+"\r\n")

}

}

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.

解决方案

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值