PHPで行うように、go(golang)で変数を代入する単純なif-elseステートメントを記述できますか?例えば:
$var = ( $a > $b )? $a: $b;
現在、私は以下を使用する必要があります:
var c int
if a > b {
c = a
} else {
c = b
}
申し訳ありませんが、この制御ステートメントと、サイト内またはGoogle検索で情報が見つからなかった場合、名前を思い出せません。:/
PHPで行うように、go(golang)で変数を代入する単純なif-elseステートメントを記述できますか?例えば:
$var = ( $a > $b )? $a: $b;
現在、私は以下を使用する必要があります:
var c int
if a > b {
c = a
} else {
c = b
}
申し訳ありませんが、この制御ステートメントと、サイト内またはGoogle検索で情報が見つからなかった場合、名前を思い出せません。:/
回答:
コメントで述べたように、Goは3成分のワンライナーをサポートしていません。私が考えることができる最も短い形式はこれです:
var c int
if c = b; a > b {
c = a
}
しかし、それを行わないでください。それだけの価値はなく、コードを読んだ人を混乱させるだけです。
listeningPath := "production.some.com"; if DEBUG { listeningPath := "development.some.com" }
プロダクション用のternaryと同じ速度で、読みやすさはかなり良いです。
他の人が述べたように、Go
は三元のワンライナーをサポートしていません。しかし、私はあなたがあなたが望むものを達成するのを助けることができる効用関数を書きました。
// IfThenElse evaluates a condition, if true returns the first parameter otherwise the second
func IfThenElse(condition bool, a interface{}, b interface{}) interface{} {
if condition {
return a
}
return b
}
これを使用する方法を示すテストケースをいくつか示します
func TestIfThenElse(t *testing.T) {
assert.Equal(t, IfThenElse(1 == 1, "Yes", false), "Yes")
assert.Equal(t, IfThenElse(1 != 1, nil, 1), 1)
assert.Equal(t, IfThenElse(1 < 2, nil, "No"), nil)
}
楽しみのために、次のような便利なユーティリティ関数を作成しました。
IfThen(1 == 1, "Yes") // "Yes"
IfThen(1 != 1, "Woo") // nil
IfThen(1 < 2, "Less") // "Less"
IfThenElse(1 == 1, "Yes", false) // "Yes"
IfThenElse(1 != 1, nil, 1) // 1
IfThenElse(1 < 2, nil, "No") // nil
DefaultIfNil(nil, nil) // nil
DefaultIfNil(nil, "") // ""
DefaultIfNil("A", "B") // "A"
DefaultIfNil(true, "B") // true
DefaultIfNil(1, false) // 1
FirstNonNil(nil, nil) // nil
FirstNonNil(nil, "") // ""
FirstNonNil("A", "B") // "A"
FirstNonNil(true, "B") // true
FirstNonNil(1, false) // 1
FirstNonNil(nil, nil, nil, 10) // 10
FirstNonNil(nil, nil, nil, nil, nil) // nil
FirstNonNil() // nil
これらのいずれかを使用する場合は、https://github.com/shomali11/utilで見つけることができます。
正解をご指摘いただきありがとうございます。
私はGolang FAQ(duh)をチェックしたところ、明確に述べられています、これは言語では利用できません:
Goには?:演算子はありますか?
Goには三元形式はありません。以下を使用して同じ結果を得ることができます。
if expr { n = trueVal } else { n = falseVal }
主題に興味があるかもしれない追加情報が見つかりました:
var c int; if a > b { c = a } else { c = b }
です。しかし、読者のレクリエーションのためのライトブロックを形成するために、5行に保つことをお勧めします;)
マップを使用してちょうど1行でこれを行うための1つの可能な方法、簡単な私がいるかどうかチェックしていますa > b
それがあるならばtrue
、私は割り当てていますc
しa
そうb
c := map[bool]int{true: a, false: b}[a > b]
ただし、これはすばらしいように見えますが、場合によっては、評価順序が原因で完全なソリューションにならないことがあります。例えば、私は、オブジェクトがされていないかどうかをチェックしていた場合nil
、それから、次のコードスニペットの意志を見て、いくつかのプロパティを取得panic
する場合のをmyObj equals nil
type MyStruct struct {
field1 string
field2 string
}
var myObj *MyStruct
myObj = nil
myField := map[bool]string{true: myObj.field1, false: "empty!"}[myObj != nil}
なぜなら、条件を評価する前にマップが最初に作成および構築されるため、myObj = nil
この場合は単にパニックになります。
条件を1行だけで実行できることを忘れないでください。以下を確認してください。
var c int
...
if a > b { c = a } else { c = b}
三項演算子の代わりにラムダ関数を使用する
例1
最大整数を与える
package main
func main() {
println( func(a,b int) int {if a>b {return a} else {return b} }(1,2) )
}
例2
must(err error)
エラーを処理するこの関数があり、条件が満たされていないときにこの関数を使用するとします。(https://play.golang.com/p/COXyo0qIslPでお楽しみください)
package main
import (
"errors"
"log"
"os"
)
// must is a little helper to handle errors. If passed error != nil, it simply panics.
func must(err error) {
if err != nil {
log.Println(err)
panic(err)
}
}
func main() {
tmpDir := os.TempDir()
// Make sure os.TempDir didn't return empty string
// reusing my favourite `must` helper
// Isn't that kinda creepy now though?
must(func() error {
var err error
if len(tmpDir) > 0 {
err = nil
} else {
err = errors.New("os.TempDir is empty")
}
return err
}()) // Don't forget that empty parentheses to invoke the lambda.
println("We happy with", tmpDir)
}
場合によっては、定義と割り当てが同じ行で行われるように無名関数を使用しようとします。以下のように:
a, b = 4, 8
c := func() int {
if a >b {
return a
}
return b
} ()
非常に類似した構文が言語で利用可能です
**if <statement>; <evaluation> {
[statements ...]
} else {
[statements ...]
}*
*
すなわち
if path,err := os.Executable(); err != nil {
log.Println(err)
} else {
log.Println(path)
}
これにはクロージャーを使用できます。
func doif(b bool, f1, f2 func()) {
switch{
case b:
f1()
case !b:
f2()
}
}
func dothis() { fmt.Println("Condition is true") }
func dothat() { fmt.Println("Condition is false") }
func main () {
condition := true
doif(condition, func() { dothis() }, func() { dothat() })
}
Goのクロージャー構文で私が持っている唯一の不満は、デフォルトのゼロパラメーターゼロの戻り関数にエイリアスがないことです。それにより、はるかに優れたものになります(型名だけでマップ、配列、およびスライスリテラルを宣言する方法を考えてください)。
または、より短いバージョンでさえ、コメンターが提案したように:
func doif(b bool, f1, f2 func()) {
switch{
case b:
f1()
case !b:
f2()
}
}
func dothis() { fmt.Println("Condition is true") }
func dothat() { fmt.Println("Condition is false") }
func main () {
condition := true
doif(condition, dothis, dothat)
}
関数にパラメーターを与える必要がある場合でも、クロージャーを使用する必要があります。これは、パラメーターがメソッドに関連付けられた構造体であると考える関数だけではなく、メソッドを渡す場合に回避できます。
doif(condition, dothis, dothat)