Kann ich eine einfache if-else-Anweisung mit variabler Zuweisung in go (golang) schreiben, wie ich es in php tun würde (zum Beispiel):
$var = ( $a > $b )? $a: $b;
momentan muss ich folgendes verwenden:
var c int
if a > b {
c = a
} else {
c = b
}
Es tut mir leid, ich kann mich nicht an den Namen erinnern, wenn diese Kontrollanweisung durch die In-Site- und Google-Suche gefunden wurde. : /
Wie bereits erwähnt, unterstützt Go keine ternären One-Liner. Die kürzeste Form, die mir einfällt, ist folgende:
var c int
if c = b; a > b {
c = a
}
Ich verwende oft folgendes:
c := b
if a > b {
c = a
}
im Grunde dasselbe wie @ Not_a_Golfer, jedoch mit Inferenz .
Wie bereits erwähnt, unterstützt Go
keine ternären Einzeiler. Ich habe jedoch eine Utility-Funktion geschrieben, mit der Sie das erreichen können, was Sie möchten.
// 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
}
Hier einige Testfälle, um zu zeigen, wie Sie es verwenden können
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)
}
Zum Spaß schrieb ich weitere nützliche Funktionen wie:
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
Wenn Sie eines davon verwenden möchten, finden Sie es hier https://github.com/shomali11/util
Danke für den Hinweis auf die richtige Antwort.
Ich habe gerade den Golang FAQ (duh) überprüft und es wird eindeutig gesagt, dass dies nicht in der Sprache verfügbar ist:
Hat Go den Operator?:?
Es gibt keine ternäre Form in Go. Sie können Folgendes verwenden, um dasselbe Ergebnis zu erzielen:
if expr { n = trueVal } else { n = falseVal }
zusätzliche Informationen gefunden, die für das Thema von Interesse sein könnten:
Eine Möglichkeit, dies in nur einer Zeile mithilfe einer Karte zu tun, prüfe ich einfach, ob a > b
, wenn es true
ist, ich c
a
zuweisen, sonst b
c := map[bool]int{true: a, false: b}[a > b]
Das sieht zwar erstaunlich aus, kann aber aufgrund der Reihenfolge der Auswertung in manchen Fällen NICHT die perfekte Lösung sein. Wenn ich zum Beispiel prüfe, ob ein Objekt nicht nil
ist und eine Eigenschaft daraus abruft, sehen Sie sich den folgenden Codeausschnitt an, der panic
im Fall von 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}
Da die Karte zuerst erstellt und erstellt wird, bevor die Bedingung ausgewertet wird, gerät dies im Fall von myObj = nil
in Panik.
Um nicht zu vergessen zu erwähnen, dass Sie die Bedingungen immer noch in einer einfachen Zeile ausführen können, überprüfen Sie Folgendes:
var c int
...
if a > b { c = a } else { c = b}
Manchmal versuche ich, eine anonyme Funktion zu verwenden, um das Definieren und Zuordnen in derselben Zeile zu erreichen. Wie unten:
a, b = 4, 8
c := func() int {
if a >b {
return a
}
return b
} ()
Verwenden Sie die Lambda-Funktion anstelle des ternären Operators
Beispiel 1
die max int geben
package main
func main() {
println( func(a,b int) int {if a>b {return a} else {return b} }(1,2) )
}
Beispiel 2
Angenommen, Sie haben diese must(err error)
-Funktion, um Fehler zu behandeln, und Sie möchten sie verwenden, wenn eine Bedingung nicht erfüllt ist. (Viel Spaß bei 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)
}
Eine sehr ähnliche Konstruktion ist in der Sprache verfügbar
**if <statement>; <evaluation> {
[statements ...]
} else {
[statements ...]
}*
*
d.h.
if path,err := os.Executable(); err != nil {
log.Println(err)
} else {
log.Println(path)
}
Sie können dafür eine Schließung verwenden:
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() })
}
Der einzige Kritikpunkt, den ich mit der Schließsyntax in Go habe, ist, dass es keinen Alias für die Standard-Nullparameter-Nullrückgabefunktion gibt. Dann wäre es viel schöner (denken Sie an, wie Sie Map-, Array- und Slice-Literale nur mit einem Typnamen deklarieren).
Oder auch die kürzere Version, als Kommentar gerade vorgeschlagen:
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)
}
Sie müssen immer noch einen Abschluss verwenden, wenn Sie den Funktionen Parameter zuweisen müssen. Dies könnte bei der Übergabe von Methoden vermieden werden, und nicht nur bei Funktionen, bei denen die Parameter die mit den Methoden verknüpfte Struktur sind.