2016-06-03 9 views
3

Ich habe ein Array von einigen Daten, die ich in []string zuordnen möchte. Ich kann es auf 2 Arten tun:Wie Art Assert-Fehler in Golang zu protokollieren?

a)

// someData 
s := someData.([]string) 

In diesem Fall würde die Ausführung stoppen, nachdem auf der Konsole die Fehler auflistet.

b)

// someData 
s, ok := someData.([]string) 

In diesem Fall würde keine Fehler auftreten, aber s wird seine Null-Wert haben


ich die Fehler in einer solchen Art Assertionsfehler Fälle protokollieren wollen, ohne zu stoppen die Hinrichtung. Wenn ich jedoch Typ (b) verwende, kann ich die Fehlerdetails nicht sehen.

Die einzige Lösung, die ich denken kann, ist, reflect.TypeOf zu verwenden und beide Typen zu drucken.

Gibt es eine andere Möglichkeit, den Fehler bei der Verwendung von Lösung (b) zu bekommen?

Antwort

8

Sie können die Protokollnachricht selbst erstellen. Explizite Aufrufe an reflect sind nicht erforderlich, da eine Druckformat-Zeichenfolge %T den Typ erzeugt.

s, ok := someData.([]string) 
if !ok { 
    log.Printf("got data of type %T but wanted []string", someData) 
    ... handle the failure somehow 
} 

ohne den Kontext zu wissen, es ist schwer für mich, eine nützliche und informative Log-Anweisung zu erzeugen, aber Sie die Idee, Ihren Anwendungsfall anpassen können angepasst werden.

+0

Verwunderlich, dass golang nicht Überprüfung erfordert, dass die Art Behauptung gültig ist. Konnte man nicht die Gültigkeit der Typ-Assertion überprüfen, die zu Laufzeitfehlern führte? – Kwestion

+0

@Kwestion Der OK-Wert gibt an, ob die Typbestätigung gültig ist. –

+0

Richtig, und wenn Sie mit importierten Daten wie einer Konfigurationsdatei oder json umgehen - es ist möglich, dass wenn Sie Typen bestätigen, Sie scheitern werden. Wenn Ihre Typbestätigung fehlschlägt, ohne ihre Gültigkeit zu überprüfen, was passiert? – Kwestion

2

Nun, je nachdem, wie Sie Ihre Typ Assertions tun möchten, gibt es eine Möglichkeit, die Fehler sowohl in Fall a) und b) zu erhalten.

So werde ich b zuerst decken, denn wenn die direkteste ist: Sie %T können die Art der Elemente zu erhalten:

func typeAssert(i interface{}) []string { 
    s, ok := i.([]string) 
    if !ok { 
     fmt.Printf("interface conversion: interface is %T, not []string\n", i) 
    } 
    return s 
} 

Der andere Weg geht von dem Fehler erholt, so dass Sie die Panik-Meldung als Fehlermeldung erhalten kann:

func assertType(i interface{}) []string { 

    // Recover 
    defer func() { 
     if err := recover(); err != nil { 
      fmt.Println(err) 
     } 
    }() 

    return i.([]string) 
} 

func main() { 
    assertType([]int{42}) 

    fmt.Println("Recovered from the error") 
} 
// OUTPUT: 
// interface conversion: interface is []int, not []string 
// Recovered from the error 

natürlich können Sie Ihre eigene Behandlung des Fehlers hinzuzufügen, abhängig von dem, was Sie tun mögen. Die erste Lösung ermöglicht sowieso mehr Flexibilität, aber recover kann manchmal nützlich sein (nicht unbedingt in diesem Fall). Hier

ist der Link zum Go playground

Verwandte Themen