Golang在另一个struct的方法中更改struct的值

时间:2016-04-09 13:25:39

标签: pointers go struct slice

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

此结构包含一些字段和一个包含切片的字段:

H = fdesign.lowpass('Fp,Fst,Ap,Ast',60,75,1,60,10000);
f = design(H,'butter','MatchExactly','passband');  % Design an FIR BW filt
info(f)                   % View information about filter
fvtool(f);
[b,a] =  sos2tf(f.sosMatrix);
fvtool(b,a);

type Bot struct { // ... connlist []Connection } 如下所示:

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) } 连接。

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

2 个答案:

答案 0 :(得分:4)

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

当您调用此ListenToConnection()方法时(您没有发布此代码),您传递的值为Connection。 Go中的所有内容都按值传递,因此将复制传递的值。在ListenToConnection()内,您使用此副本进行操作。您调用其activateConn()方法,但该方法(具有指针接收器)将接收此副本的地址(本地变量)。

解决方案很简单,将ListenToConnection()的参数更改为指针:

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

使用Bot.connlist

中的值调用它
bot.ListenToConnection(&bot.connlist[0])

for循环使用conlist的每个元素调用它:

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

答案 1 :(得分:1)

它需要切片连接指针。 如果此属性将同时更改,则信号量是必要的。

type Bot struct {
    // ...
    conns []*Connection
}

func (bot *Bot) ListenToConnection(c *Connection) {
   // code
}

type Connection struct {
    conn         net.Conn
    messages     int32
    channels     []string
    joins        int32
    isActive     bool
    isActiveLock sync.RWMutex
}

func (c *Connection) activateConn() {
    c.isActiveLock.Lock()
    defer c.isActiveLock.Unlock()

    c.isActive = true
}