2014-12-25 1 views
6

Sto provando a scrivere una funzione Map, in modo che possa gestire tutti i tipi di array.Come scrivere func per il parametro generico in golang

// Interface to specify generic type of array. 
type Iterable interface { 
} 

func main() { 
    list_1 := []int{1, 2, 3, 4} 
    list_2 := []uint8{'a', 'b', 'c', 'd'} 
    Map(list_1) 
    Map(list_2) 
} 

// This function prints the every element for 
// all []types of array. 
func Map(list Iterable) { 
    for _, value := range list { 
     fmt.Print(value) 
    } 
} 

Ma genera l'errore di compilazione.

19: cannot range over list (type Iterable) 

L'errore è corretto perché range richiedono matrice, puntatore a un array, slice, stringa, carta, o un canale consentendo operazioni di ricezione e qui tipo è Iterable. Penso che il problema che sto affrontando sia la conversione del tipo di argomento Iterable in un tipo di array. Si prega di suggerire, come potrei usare la mia funzione per gestire array generico.

risposta

5

Come Rob Pike menzioni in this thread

E 'possibile esprimere "qualsiasi mappa", "qualsiasi array" o "ogni fetta" di un interruttore di tipo Go?

No. I tipi statici devono essere esatti.
L'interfaccia vuota è davvero un tipo, non un carattere jolly.

Si può solo iterare su un elenco di un tipo specifico, come un'interfaccia con funzioni note.
Si può vedere un esempio con "Can we write a generic array/slice deduplication in go?"

Anche utilizzando la riflessione, per passare una porzione come interface{} sarebbe, come this thread shows, incline all'errore (vedi this example).

+0

sarebbe possibile conoscere il tipo e il valore dall'argomento dell'interfaccia? Sto ancora cercando di capirlo dall'esempio condiviso. –

+0

@ subh.singh non in modo dinamico, motivo per cui è meglio lavorare con un array di un'interfaccia conosciuta, invece di un 'interface {}'. – VonC

+1

@ subh.singh almeno non senza riflessione, un po 'come in http://play.golang.org/p/jxMFq5UYs1 menzionato nei commenti di https://www.tbray.org/ongoing/When/201x/2013/07/15/Golang-Diaries-2. – VonC

0

La definizione di mappa non è completa. Il modo usuale per dichiararlo avrebbe un metodo mapper. Il vostro esempio può essere implementato almeno in questo modo

package main 

import "fmt" 

// Interface to specify something thet can be mapped. 
type Mapable interface { 
} 


func main() { 
    list_1 := []int{1, 2, 3, 4} 
    list_2 := []string{"a", "b", "c", "d"} 
    Map(print, list_1) 
    Map(print, list_2) 
} 
func print(value Mapable){ 
fmt.Print(value) 
} 

// This function maps the every element for 
// all []types of array. 
func Map(mapper func(Mapable), list ... Mapable) { 
    for _, value := range list { 
     mapper(value) 
    } 
} 

E works. Devo dire che è un po 'non tipizzato. Perché no, Go non ha "generici" in Hindley-Milner sence

+0

Penso che se vogliamo eseguire qualche operazione sugli elementi dell'array, allora dobbiamo andare con la riflessione. Nell'esempio corrente stiamo stampando il valore, non facendo alcuna operazione sugli elementi. –