webentwicklung-frage-antwort-db.com.de

Wie mache ich einen Einzeiler, wenn sonst eine Aussage?

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. : /

56
thoroc

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
}
85
Not_a_Golfer

Ich verwende oft folgendes:

c := b
if a > b {
    c = a
}

im Grunde dasselbe wie @ Not_a_Golfer, jedoch mit Inferenz .

22
xoyuz

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

15
Raed Shomali

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:

9
thoroc

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 ca 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}
2
msoliman

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
  } ()

https://play.golang.org/p/rMjqytMYeQ0

1
Ron

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)
}
0
Alice Vixie

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)
}
0
user2680100

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.

0
Louki Sumirniy