457

C/C++ (およびそのファミリの多くの言語) では、条件に応じて変数を宣言および初期化するための一般的なイディオムは、三項条件演算子を使用します。

int index = val > 0 ? val : -val

Go には条件演算子がありません。上記と同じコードを実装する最も慣用的な方法は何ですか? 次の解決策にたどり着きましたが、かなり冗長なようです

var index int

if val > 0 {
    index = val
} else {
    index = -val
}

もっと良いものはありますか?

4

11 に答える 11

381

指摘したように (そして、当然のことながら)、usingif+elseは実際に Go で条件分岐を実行するための慣用的な方法です。

ただし、完全なコード ブロックに加えてvar+if+else、次のスペルもよく使用されます。

index := val
if val <= 0 {
    index = -val
}

と同等のものなど、十分に反復的なコードのブロックがある場合は、int value = a <= b ? a : bそれを保持する関数を作成できます。

func min(a, b int) int {
    if a <= b {
        return a
    }
    return b
}

...

value := min(a, b)

コンパイラはそのような単純な関数をインライン化するため、高速で、より明確で、短くなります。

于 2013-11-14T14:08:47.773 に答える
133

No Go には三項演算子がありません。if/else 構文を使用するの慣用的な方法です。

Go に ?: 演算子がないのはなぜですか?

Go には 3 項テスト操作はありません。以下を使用して同じ結果を得ることができます。

if expr {
    n = trueVal
} else {
    n = falseVal
}

Go が欠落している理由?:は、この言語の設計者が、非常に複雑な式を作成するために操作が頻繁に使用されるのを見てきたからです。フォームは長くなりますif-elseが、間違いなく明確です。言語には、条件付き制御フロー構造が 1 つだけ必要です。

— よくある質問 (FAQ) - Go プログラミング言語

于 2013-11-14T13:44:42.067 に答える
74

次の三項式があるとします (C):

int a = test ? 1 : 2;

Go での慣用的なアプローチは、単純にifブロックを使用することです。

var a int

if test {
  a = 1
} else {
  a = 2
}

ただし、それは要件に合わない場合があります。私の場合、コード生成テンプレートのインライン式が必要でした。

すぐに評価される匿名関数を使用しました。

a := func() int { if test { return 1 } else { return 2 } }()

これにより、両方のブランチも評価されなくなります。

于 2016-01-06T15:18:48.580 に答える
52

マップ三項は括弧なしで読みやすいです:

c := map[bool]int{true: 1, false: 0} [5 > 4]
于 2015-07-17T19:57:53.177 に答える
3

eold の答えは興味深く、創造的で、おそらく賢いものです。

ただし、代わりに次のことをお勧めします。

var index int
if val > 0 {
    index = printPositiveAndReturn(val)
} else {
    index = slowlyReturn(-val)  // or slowlyNegate(val)
}

はい、両方とも本質的に同じアセンブリにコンパイルされますが、このコードは、最初に変数に書き込むことができた値を返すためだけに無名関数を呼び出すよりもはるかに読みやすいです。

基本的に、シンプルで明確なコードはクリエイティブなコードよりも優れています。

さらに、Go ではマップはまったく軽量ではないため、マップ リテラルを使用するコードはお勧めできません。Go 1.3以降、小さなマップのランダムな反復順序が保証されています.これを強制するために、小さなマップのメモリ効率はかなり低下しています.

その結果、多数の小さなマップを作成および削除するには、スペースと時間がかかります。小さなマップを使用するコードがありました (2 つまたは 3 つのキーである可能性が高いですが、一般的な使用例は 1 つのエントリのみでした)。しかし、コードは非常に低速でした。デュアル スライス key[index]=>data[index] マップを使用するように書き直された同じコードよりも、少なくとも 3 桁は遅くなります。そしておそらくもっとでした。以前は実行に数分かかっていた一部の操作が、ミリ秒単位で完了するようになりました.\

于 2016-05-13T00:53:58.947 に答える