私のゴーコードには競合状態があります。しかし、私は正しく同期していると確信しているので、私はそれを見つけることができません。数時間のデバッグの後、おそらく私はそれを見つけるのを助けることができます。Golang:関数タイプが異常な動作
package main
import (
"log"
"time"
)
type Parser struct {
callback Callback
callbackSet chan bool
test int
}
func NewParser() Parser {
p := Parser{}
p.test = 100
p.callbackSet = make(chan bool)
return p
}
func (p *Parser) SetCallback(newCallback Callback) {
log.Println("=> SET CALLBACK: ", newCallback)
p.test = 100
p.callback = newCallback
log.Println("=> SETTING CALLBACK DONE")
p.callbackSet <- true
}
func (p *Parser) StartParsing() {
go p.parse()
}
func (p *Parser) parse() {
cb := <-p.callbackSet
_ = cb
log.Println("Verify Callback: ", p.callback)
log.Println("Verify Test Variable: ", p.test)
funcDone := make(chan bool)
go func() {
time.Sleep(3 * time.Second) // Some io-Operation here
funcDone <- true
}()
_ = <-funcDone
}
type Callback func(Message)
type Message int
type Dialog struct {
Parser Parser
}
func CreateDialog() (Dialog, error) {
d := Dialog{}
d.Parser = NewParser()
d.Parser.StartParsing()
return d, nil
}
func (d *Dialog) OnMessage(callback Callback) {
log.Println("dialog.OnMessage: ", callback)
time.Sleep(3 * time.Second) // This sleep is just to prove the synchronization. It could be removed.
d.Parser.SetCallback(callback)
}
func main() {
dialog, _ := CreateDialog()
dialog.OnMessage(func(m Message){
log.Println("Message: ", m)
})
time.Sleep(5 * time.Second) // Not clean but just to await all of the output
}
大きな問題は今:これら二つは全く同じに設定されているが、なぜp.callback
<nil>
がp.test
一方p.parse
であるが、ではありません
まず第一に、ここで私の(非常に単純化された)コードです時間?
また、チャンネルp.callbackSet
を使用して同期する必要がありますか? https://play.golang.org/p/14vn5Tie5Y
で
完全に実行可能な例では、私は単純な一つによって主な機能を交換しようとしました。私はバグがDialog
構造体のどこかにあると思われます。その使用方法を回避すると、問題を再現できません。
func main() {
p := NewParser()
p.StartParsing()
p.SetCallback(func (m Message) {
log.Println("Message: ", m)
})
time.Sleep(5 * time.Second) // Not clean but just to await all of the output
}
残りのコードは同じです。ここで変更(作業)バージョンの他の再生可能な例:あなたは値によってParser
オブジェクトを格納し、CreateDialog
からの値によってDialog
を戻ってきているので、https://play.golang.org/p/0Y0nKbfcrv
答えは(現在)間違っていますが、私は遊び場を見ました:問題は '' Set.callback() 'で' 'p.test'を変更しようとしたように、' 'p.callback'後でデフォルト値。 –