3

この遊び場を考えると:

package main

import "fmt"

func main() {
    go oneFunc().anotherFunc()
}

func oneFunc() something {
    fmt.Println("oneFunc")
    return something{}
}

type something struct{}

func (s something) anotherFunc() {
    fmt.Println("anotherFunc")
}

出力はなぜですか:

ワンファンクション

「anotherFunc」は印刷されませんか?

4

3 に答える 3

5

anotherFunconeFunc値が返されるまで実行されません。このため、プログラムはanotherFunc実行可能になる前に終了します。anotherFunc終了する前に実行を待つ必要がありmainます。

これは、Go チャネルを介して行うことができます。例えば:

http://play.golang.org/p/dWoLB9afSj

package main

import "fmt"

func main() {
    ch := make(chan int)
    go oneFunc(ch).anotherFunc()
    fmt.Println("Waiting...")
    <-ch
    fmt.Println("Done.")
}

func oneFunc(ch chan int) something {
    fmt.Println("oneFunc")
    return something{ch}
}

type something struct{
    ch chan int
}

func (s something) anotherFunc() {
    fmt.Println("anotherFunc")
    s.ch <- 1
}
于 2013-11-05T22:42:15.767 に答える
2

キーワードの背後にある式goが評価され、その式の関数値が同時に実行されます。

したがって、あなたの例oneFunc()では呼び出されるため、oneFunc出力とanotherFunc、返されたインスタンスのメソッドが同時に呼び出されます。ただし、ゴルーチンが実行される前にプログラムが終了するため、表示されませんanotherFunc

解決策:sync.WaitGroupまたはチャネルを使用して同期します。

実際に(経験的に)go呼び出しがanotherFunc同時に実行され、各関数のスタックを出力して出力を比較できないことを確認するには。 oneFunc例 (プレイ中):

var wg = sync.WaitGroup{}

func main() {
    wg.Add(1)
    go oneFunc().anotherFunc()
    wg.Wait()
}

func oneFunc() something {
    fmt.Println("oneFunc")

    buf := make([]byte, 4096)
    runtime.Stack(buf, false)
    fmt.Println("Stack of oneFunc:", string(buf))

    return something{}
}

type something struct{}

func (s something) anotherFunc() {
    defer wg.Done()

    buf := make([]byte, 4096)
    runtime.Stack(buf, false)
    fmt.Println("Stack of anotherFunc:", string(buf))

    fmt.Println("anotherFunc")
}

次のようなものが表示されます。

oneFunc
Stack of oneFunc: goroutine 1 [running]:
main.oneFunc()
    /tmpfs/gosandbox-342f581d_b6e8aa8b_334a0f88_c8221b7e_20882985/prog.go:20 +0x118
main.main()
    /tmpfs/gosandbox-342f581d_b6e8aa8b_334a0f88_c8221b7e_20882985/prog.go:11 +0x50

Stack of anotherFunc: goroutine 2 [running]:
main.something.anotherFunc()
    /tmpfs/gosandbox-342f581d_b6e8aa8b_334a0f88_c8221b7e_20882985/prog.go:32 +0xb2
created by main.main
    /tmpfs/gosandbox-342f581d_b6e8aa8b_334a0f88_c8221b7e_20882985/prog.go:11 +0x69

anotherFunc

スタック トレースは、2 つの関数が異なるゴルーチンで実行されていることも示しており、メソッド呼び出しの比較は必要ありません。

于 2013-11-05T23:10:30.980 に答える