问题描述
这个结构体有一些字段和一个包含切片的字段:
类型Bot结构{
// ...
connlist []连接
}
这个 Connection 看起来像这样:
类型连接结构{
conn net.Conn
messages int32
channels [] string
连接int32
connactive bool
}
我的问题是改变数值 connactive 至 true 。
Bot 有一个侦听连接的方法:
func(bot * Bot)ListenToConnection (connection connection){
reader:= bufio.NewReader(connection.conn)
tp:= textproto.NewReader(reader)
用于{
行,err:= tp。 ReadLine()
如果err!= nil {
log.Printf(错误读取聊天连接:%s,错误)
break //错误循环break
}
如果strings.Contains(line, tmi.twitch.tv 001){
connection.activateConn()
}
如果strings.Contains(line,PING){
fmt.Fprintf(connection.conn ,PONG tmi.twitch.tv\r\\\
)
}
fmt.Fprintf(bot.inconn,line +\r\\\
)
}
$ b $ connection.activeConn()是不正常工作的部分,方法如下所示:
func(connection * Connection)activateConn(){
connection.connactive = true
}
这实际上被执行,所以它不是连接问题没有得到响应或什么。
但是,如果我稍后以 Bot , connactive 总是 false 出于某种原因(这是默认值)。
for i:= 0;我< 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])
循环用 conlist $ c $>的每个元素调用它
:
for i:=范围bot.connlist {
bot.ListenToConnection(&bot.conlist [i])
}
注意!我故意将用于......范围,它只使用索引而不是值。使用一个作为...... range 的索引和值,或者只是该值,你会观察到同样的问题( connactive 将保持 false ):
for _,v:= range bot.connlist {
bot.ListenToConnection(& v)//不好! v也是副本
}
因为 v 也只是一个副本,将它的地址传递给 bot.ListenToConnection(),它只会指向副本而不是<$ c $中的元素c> connlist 切片。
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.
这篇关于Golang在另一个结构的方法内改变一个结构体的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-02 02:19