Umwandeln unbekannte Schnittstelle zu float64 in Golang
So, ich erhalte eine Schnittstelle{}, aber ich möchte in jeder möglichen Weise zu konvertieren, um ein float64 oder einen Fehler zurückgeben, falls nicht möglich.
Hier ist, was ich Tue:
func getFloat(unk interface{}) (float64, error) {
if v_flt, ok := unk.(float64); ok {
return v_flt, nil
} else if v_int, ok := unk.(int); ok {
return float64(v_int), nil
} else if v_int, ok := unk.(int16); ok {
return float64(v_int), nil
} else ... //other integer types
} else if v_str, ok := unk.(string); ok {
v_flt, err := strconv.ParseFloat(v_str, 64)
if err == nil {
return v_flt, nil
}
return math.NaN(), err
} else if unk == nil {
return math.NaN(), errors.New("getFloat: unknown value is nil")
} else {
return math.NaN(), errors.New("getFloat: unknown value is of incompatible type")
}
}
Aber ich fühle mich wie ich über Sie gehen den falschen Weg, gibt es einen besseren Weg, dies zu tun?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dave C eine gute Antwort mit
reflect
, und ich werde vergleichen Sie das mit Typ-Typ-code unten. Erstens, zu tun, was Sie bereits getan haben, prägnanter, können Sie die Typ-Schalter:Den
case float64:
ist wie Ihreif i, ok := unk.(float64); ok { ... }
. Code für den Fall, dass ein Zugriff auf diefloat64
alsi
. Trotz der fehlenden geschweiften Klammern die Fälle handeln, wie Blöcke:i
's Typ ist anders unter jedemcase
und es gibt keine C-style-fallthrough.Beachten Sie auch, groß
int64
s (über 253) gerundet werden bei der Konvertierung infloat64
, so, wenn Sie denkenfloat64
als "universal" Typ Zahl, nehmen Ihre Einschränkungen zu berücksichtigen.Ein Beispiel dafür ist der Spielplatz am http://play.golang.org/p/EVmv2ibI_j.
Dave C erwähnt Sie kann vermeiden Sie das schreiben von einzelnen Fällen, wenn Sie
reflect
; seine Antwort-code, und auch Griffe benannte Typen und Hinweise auf geeignete Arten. Er erwähnt auch die Handhabung von strings und Arten Cabrio zu Ihnen. Nach einem naiven test Vergleich Optionen:reflect
version eine int bekommt der von mir über 3 Millionen Konvertierungen pro Sekunde; der overhead ist nicht erkennbar, es sei denn, Sie konvertieren, Millionen von Artikeln.reflect
; das ist ein wenig schneller für die gängigsten Typen (9m/s), aber behält die Flexibilität desreflect
code.switch
nur über Anzahl Arten verliert einige Flexibilität, aber kann squeeze-out einige zusätzliche perf, weil escape-Analyse bestimmen kann, seine Eingabe nicht entkommen.Den code auf dem Spielplatz und unten:
case int, int32, int64: return float64(t)
type myFloat float64
. Sie verwenden sollten, spiegeln dieConvertibleTo
, (möglicherweise mit einem zusätzlichen Versuch, um zu analysieren, alles konvertierbar-auf einen string).Können Sie das spiegeln-Paket dieses:
Thread in der Spielwiese: http://play.golang.org/p/FRM21HRq4o