ホームページ > バックエンド開発 > Golang > WaitGroup の Add、Done、および Wait 関数は、変数として宣言されている場合でもポインターを使用して呼び出されるのはなぜですか?

WaitGroup の Add、Done、および Wait 関数は、変数として宣言されている場合でもポインターを使用して呼び出されるのはなぜですか?

DDD
リリース: 2024-11-26 04:13:18
オリジナル
412 人が閲覧しました

Why are WaitGroup's Add, Done, and Wait functions called using a pointer even when declared as a variable?

WaitGroups リファレンスのポインターまたは変数

同期パッケージ内では、WaitGroups の Add、Done、および Wait 関数はすべて、 WaitGroup へのポインタ。ただし、次のコードはこの規則に矛盾しているようです。

package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, wg *sync.WaitGroup) {

    defer wg.Done()

    fmt.Printf("Worker %d starting\n", id)

    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
}

func main() {

    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }

    wg.Wait()
}
ログイン後にコピー

このコードでは、Done はポインター変数を使用して呼び出されますが、Add と Wait は (ポインターではなく) 変数を使用して呼び出されます。

説明:

変数宣言 var wg sync.WaitGroup にもかかわらず、 Add、Done、および Wait 関数には、ポインター レシーバー (*WaitGroup) を介してアクセスします。 wg の値は、Go コンパイラーによって暗黙的にポインターに変換されます。これが必要なのは、次の関数宣言に見られるように、メソッドがポインター レシーバーとして定義されているためです。

Add -------> func (wg *WaitGroup) Add(delta int)
Done ------> func (wg *WaitGroup) Done()
Wait ------> func (wg *WaitGroup) Wait()
ログイン後にコピー

ポインター以外の値をポインター レシーバー メソッドに渡すと、コンパイラーは自動的にそのアドレス (ポインター値に)。したがって、wg が変数として宣言されている場合でも、3 つの関数はすべて wg へのポインターで呼び出されます。

ポインター レシーバーを使用する主な理由は、データの不必要なコピーを避けることです。ポインターを渡すことにより、関数は基になる WaitGroup のコピーを作成するのではなく、直接変更できます。これにより、特に頻繁に変更される WaitGroups のパフォーマンスが向上します。

提供されたコードでは、wg のアドレスをワーカーに渡すことが重要です。これは、wg が値として (& なしで) 渡された場合、Done 関数が各ワーカーは、メイン関数の Add および Wait とは異なるポインターを参照します。これにより、誤った動作が発生します。

以上がWaitGroup の Add、Done、および Wait 関数は、変数として宣言されている場合でもポインターを使用して呼び出されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート