2016-10-31 3 views
1

Ich bin noob in Go :) so meine Frage kann dumm sein, kann aber keine Antwort finden, so.Wie überprüfe ich, ob die Schnittstelle {} eine Scheibe ist

Ich brauche eine Funktion:

func name (v interface{}) { 
    if is_slice() { 
     for _, i := range v { 
      my_var := i.(MyInterface) 
      ... do smth 
     } 
    } else { 
     my_var := v.(MyInterface) 
     ... do smth 
    } 
} 

Wie kann ich is_slice in Go tun? Schätze jede Hilfe.

+0

Eigentlich ist mein Problem, dass v ein Stück Zeiger ist. Nach einigem Nachforschen denke ich, dass es besser ist, über die Sammlung an erster Stelle zu iterieren, zumindest die Implementierung, die ich gesehen habe, verwendete einen solchen Ansatz. Einige Copy/Paste-Boilerplate-Code, aber ich denke, es wird kein Problem für jetzt – Alexander

Antwort

4

In Ihrem Fall die type switch ist die einfachste und bequemste Lösung:

func name(v interface{}) { 
    switch x := v.(type) { 
    case []MyInterface: 
     fmt.Println("[]MyInterface, len:", len(x)) 
     for _, i := range x { 
      fmt.Println(i) 
     } 
    case MyInterface: 
     fmt.Println("MyInterface:", x) 
    default: 
     fmt.Printf("Unsupported type: %T\n", x) 
    } 
} 

Die case Zweige aufzählen die möglichen Typen, und in ihnen die x Variable wird bereits von diesem Typ sein, so können Sie es verwenden damit.

Testing es:

type MyInterface interface { 
    io.Writer 
} 

var i MyInterface = os.Stdout 
name(i) 
var s = []MyInterface{i, i} 
name(s) 
name("something else") 

Output (versuchen Sie es auf dem Go Playground):

MyInterface: &{0x1040e110} 
[]MyInterface, len: 2 
&{0x1040e110} 
&{0x1040e110} 
Unsupported type: string 

Für einen einzigen Typ überprüfen Sie auch type assertion verwenden:

if x, ok := v.([]MyInterface); ok { 
    // x is of type []MyInterface 
    for _, i := range x { 
     fmt.Println(i) 
    } 
} else { 
    // x is not of type []MyInterface or it is nil 
} 

Es gibt auch andere Möglichkeiten, mit Paket reflect können Sie eine allgemeine (und schreiben langsamere) Lösung, aber wenn du gerade Go startest, solltest du noch nicht ins Nachdenken vertiefen.

3

icza's answer korrekt ist, aber wird nicht empfohlen, von go creators:

Schnittstelle {} sagt nichts

Ein besserer Ansatz eine Funktion für jeden Typ zu definieren sein können Sie haben:

func name(v MyInterface) { 
    // do something 
} 

func names(vs []MyInterface) { 
    for _, v := range(vs) { 
     name(v) 
    } 
} 
+0

Fragen, warum Ersteller von FMT-Paket Druckfunktion für jeden Typ nicht erstellt? – Alexander

+0

Danke für interessanten Link. – Alexander

+0

@Alexander haben Sie eine etwas "Druck für jeden Typ" als die Print-Verben implementiert:% s für Strings,% p für Zeiger,% d für ganze Zahlen der Basis 10, etc, und Sie können% s verwenden und implementieren Sie Ihre eigenen String() String-Funktion, um Ihren eigenen Typ zu drucken –

Verwandte Themen