2015-07-11 4 views
2

У меня есть эта функция, и я бы хотел, чтобы она могла получать все типы срезов, а не только [] string, но [] int и т. Д. Я бы хотел знаете, есть ли какой-то способ абстрагировать тип при передаче параметра в заголовок функции, или если я должен сделать что-то другое, чтобы это сделать.Передача параметров другого типа функции

package removeDuplicate 

// RemoveDuplicate remove duplicate items from slice setting it to arr2 
func RemoveDuplicate(arr []string) []string { 
    arr2 := arr[:1] 
Loop: 
    for i := 1; i < len(arr); { 
     for j := 0; j < len(arr2); { 
      if arr[i] != arr[j] { 
       j++ 
      } else { 
       i++ 
       continue Loop 
      } 
     } 
     arr2 = append(arr2, arr[i]) 
     i++ 
    } 
    return arr2 
} 

Заранее спасибо =]

+1

Это ломтики, а не массивы. Это важно, потому что с помощью срезов вы можете работать с одними и теми же данными, а массивы - это отдельные значения. –

+0

Примечание: если срез (как уже отмечалось, * не * массив) может быть большим, то лучшей реализацией будет построение карты (фактически набора) из входного среза, а затем превращение ключей карты в срез для вернуть. Если такого рода действия выполняются часто, то исходный тип данных должен быть изменен как карта (или составной объект, который включает карту). –

+0

Да, я должен сказать кусочек в этом случае. Но поскольку срез описывает раздел массива, это что-то заставляет меня смутить, почему я не могу назвать его массивом - более обобщенным способом. –

ответ

3

Если изменить сигнатуру, чтобы принять интерфейс {} вы можете получить то, что работает на встроенных типов.

package main 

import "fmt" 

func main() { 
    x := []interface{}{"bob", "doug", "bob"} 
    fmt.Println(RemoveDuplicate(x)) 
    y := []interface{}{1, 3, 1} 
    fmt.Println(RemoveDuplicate(y)) 
    z := []interface{}{"bob", "2", "doug", 3, 2, "bob"} 
    fmt.Println(RemoveDuplicate(z)) 
} 

func RemoveDuplicate(arr []interface{}) []interface{} { 
    arr2 := arr[:1] 
Loop: 
    for i := 1; i < len(arr); { 
     for j := 0; j < len(arr2); { 
      if arr[i] != arr[j] { 
       j++ 
      } else { 
       i++ 
       continue Loop 
      } 
     } 
     arr2 = append(arr2, arr[i]) 
     i++ 
    } 
    return arr2 
} 

Посмотрите часто задаваемые вопросы Can I convert a []T to an []interface{}? (и один ранее) для получения дополнительной информации.

+0

Спасибо, он отлично работает и кажется очень идиоматичным. –

0

Любой тип общих алгоритмов в Go может быть реализован с помощью одного из двух механизмов: интерфейсов и отражения. С интерфейсами, вы можете сделать это так же, как в sort упаковке:

type Slice interface { 
    Len() int 
    Swap(i, j int) 
    Eq(i, j int) bool 
    SubSlice(i, j int) Slice 
} 

func RemoveDuplicate(s Slice) Slice { 
    n := 1 
Loop: 
    for i := 1; i < s.Len(); i++ { 
     for j := 0; j < n; j++ { 
      if s.Eq(i, j) { 
       continue Loop 
      } 
     } 
     s.Swap(n, i) 
     n++ 
    } 
    return s.SubSlice(0, n) 
} 

площадка с Интс и строк: http://play.golang.org/p/WwC27eP72n.

Смежные вопросы