Go 関数の戻り値: "Comma Ok" パターンの解読
Go では、関数は複数の値を返すことができるため、便利です。特定のシナリオでは。ただし、すべての複数値の戻り値が有効であるわけではありません。次のコード スニペットは有効なケースを示しています:
func FindUserInfo(id string) (Info, bool) { it, present := all[id] return it, present }
逆に、このコードは無効です:
func FindUserInfo(id string) (Info, bool) { return all[id] }
なぜ最初の例は有効で、2 番目の例は無効なのでしょうか?これを理解するには、「カンマ OK」パターンとして知られるテクニックを詳しく掘り下げる必要があります。
「カンマ OK」のイディオム: 欠落しているキーとゼロ値のロックを解除する
「カンマ OK」 ok」イディオムは、マップ内の欠落しているエントリとゼロ値を区別するために使用されます。このパターンは、マップ キーにアクセスするときに特によく見られます。次の点を考慮してください:
var seconds int var ok bool seconds, ok = timeZone[tz]
tz キーが timeZone マップに存在する場合、秒には対応する値が割り当てられ、ok は true に設定されます。それ以外の場合、秒は 0 に設定され、ok は false に設定されます。
実装の詳細: Go のソース コードを詳しく見る
説明を求めて、Go のソース コードに戻ります。ソースコード。 unpack メソッドは、複数値の割り当てと戻り値の処理を担当します。次の基準に基づいて、特定の式が「カンマ OK」ケースに該当するかどうかを決定します:
複数値の代入の場合、「comma ok」パターンを有効にするには、allowCommaOk パラメーターを true に設定する必要があります。ただし、Go コンパイラーでは、このパラメーターは一貫して false に設定されます。
複数値の戻り値の結果
この動作は、「comma ok」パターンが可能であることを意味します。代入コンテキストでのみ使用してください。関数から複数の値を取得するには、代入の左側の変数が必要です。
詳細な例
説明するために、チェッカーを調べます。 .initVars() メソッド:
var x operand if commaOk { var a [2]Type for i := range a { get(&x, i) a[i] = check.initVar(lhs[i], &x, returnPos.IsValid()) } check.recordCommaOkTypes(rhs[0], a) return }
このコードでは、commaOk フラグは、代入の左側の変数の数が関数によって返される値の数と一致する場合にのみアクティブになります。したがって、取得する値ごとに変数を宣言する必要があります。
結論
Go の "comma ok" パターンは、値を区別するための貴重なツールです。欠落しているマップ エントリとゼロ値の間。ただし、その適用範囲は割り当てコンテキストに限定されており、戻り値を格納するには変数を使用する必要があります。これらの制約を理解することで、Go コードで複数値の戻り値を正しく効率的に実装できるようになります。
以上がGo 関数から複数の値を返す場合、「カンマ OK」パターンが代入コンテキストでのみ適用されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。