2015-06-08 5 views
15

Wie kann ich den benutzerdefinierten Typ in interface{} und dann in den Basistyp konvertieren (z. B. uint8)?Geben Sie benutzerdefinierte Cast-Typen zu Basistypen ein

ich nicht direkt Guss wie uint16(val.(Year)) verwenden kann, weil ich nicht alle benutzerdefinierten Typen wissen kann, aber ich kann in Basistypen (uint8, uint32, ...) Laufzeit


Es gibt viele individuelle Bestimmtes Typen auf Basis von numerischen (in der Regel als Aufzählungen verwendet):

ex:

type Year uint16 
type Day uint8 
type Month uint8 

und so weiter ...

Die Frage ist, über Art Gießen von interface{} auf Basistypen:

package main 

import "fmt" 

type Year uint16 

// .... 
//Many others custom types based on uint8 

func AsUint16(val interface{}) uint16 { 
    return val.(uint16) //FAIL: cannot convert val (type interface {}) to type uint16: need type assertion 
} 

func AsUint16_2(val interface{}) uint16 { 
    return uint16(val) //FAIL: cannot convert val (type interface {}) to type uint16: need type assertion 
} 

func main() { 
    fmt.Println(AsUint16_2(Year(2015))) 
} 

http://play.golang.org/p/cyAnzQ90At

+3

Bitte beachten Sie, dass weder 'val (unit16)' 'noch uint16 (val)' ist eine "Besetzung". Die erste ist eine "Art Behauptung" und die zweite und "Typumwandlung". – Volker

Antwort

12

Sie dies mit dem reflect Paket ausführen können:

package main 

import "fmt" 
import "reflect" 

type Year uint16 

func AsUint16(val interface{}) uint16 { 
    ref := reflect.ValueOf(val) 
    if ref.Kind() != reflect.Uint16 { 
     return 0 
    } 
    return uint16(ref.Uint()) 
} 

func main() { 
    fmt.Println(AsUint16(Year(2015))) 
} 

Je nach Ihrer Situation, Sie Vielleicht möchten Sie (uint16, error) zurückgeben, anstatt den leeren Wert zurückzugeben.

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

4

Warum Sie in der Frage enthalten Year haben? Hoffen Sie, beliebige Dinge in Jahre umzuwandeln oder Jahre in uint16s umzuwandeln?

Wenn ich nehme an, Sie den letzteren Fall gemeint, dann wäre es besser, ein Verfahren

func (y Year) AsUint16() uint16 { 
    return uint16(y) 
} 

zu verwenden, die keine Art Behauptungen oder Reflexion benötigt.

https://play.golang.org/p/9wCQJe46PU

+0

Ich habe viele (N) benutzerdefinierte Typen basierend auf einfachen Typen (uint8, 16, 32 ...). Und ich möchte nicht N Methoden anstelle der eine erstellen –

+0

Das ist fair, aber es ist wert, die Vor- und Nachteile von jedem Ansatz abwägen. Der explizite Ansatz, den ich oben beschrieben habe, ist einfach, schnell und typensicher, aber möglicherweise zu ausführlich. Die reflektierende Herangehensweise wird langsamer und weniger explizit in dem sein, was es für Leute macht, die mitkommen und Ihren Code lesen. –

+0

FWIW, ich habe mich mit einer ähnlichen Situation beschäftigt, indem ich [Gen] (https://github.com/clipperhouse/gen) verwende, um Code aus Vorlagen zu erstellen, aber in Ihrem Fall ist es keine zwingende Wahl. –

Verwandte Themen