根据输入切片参数创建执行不同操作的函数

时间:2017-12-13 00:40:08

标签: arrays go slice

我刚开始学习Go语言,我想构建一个从切片中选择随机子序列的函数。但是,我不知道这个切片可以存储什么类型的值,这些值可以是整数,字符串或某些结构的元素。例如,让我们假设我必须结构:

type person struct {
    name string
    age  int
}

type animal struct {
    name  string
    age   int
    breed string
}

现在,我想构建函数getRandomSequence,如下所示:作为参数给出切片S和长度l,该函数返回一个切片,其中包含来自切片S的l个随机选择的元素。我遇到的问题是 - 如何使这个函数适用于任何可能的切片。我试着做以下事情:

func GetRandomSequence(S interface{}, l int) []interface{} {
   switch S.(type) {
   case person:
      // Do random selection of l elements from S and return them
   case animal:
      // Do random selection of l elements from S and return them
   case int:
     // Do random selection of l elements from S and return them
   }
   return " Not Recognised"
}

有人可以建议我怎么写这样的功能吗?如果S是任何类型的单个元素,那么我设法使类似(即一般)函数起作用(因此[]interface{}只是interface{}而不是UniversalAuthorizer}但我无法找到如何解决这个问题

2 个答案:

答案 0 :(得分:1)

只需使用interface{}而不是[]interface{}。空接口可以存储任何类型,包括切片。

您的代码看起来像这样(虽然我没有测试):

func GetRandomSequence(S interface{}, l int) interface{} {
   returnSlice := []interface{}
   switch v := s.(type) {
   // inside the switch v has the value of S converted to the type
   case []person:
      // v is a slice of persons here
   case []animal:
      // v is a slice of animals here
   case []int:
      // v is a slice of ints here
   case default:
       // v is of type interface{} because i didn't match any type on the switch
       // I recommend you return nil on error instead of a string
       // or always return 2 things, the value and an error like 
       // the standard library
       return "Not Recognized" 
   }
   rerurn returnSlice
}

我建议您完成Tour of go,但对于这个问题,答案是here

根据您想要做的事情,看起来您可能不需要不同类型的切片,只需要一片interface{}。如果在你的函数中从切片中提取随机元素,你就不关心元素的类型了:

func GetRandomSequence(S []interface{}, l int) []interface{} {
    returnSlice := make([]interface{}, 0, l)
    for i:=0; i<l; i++ { 
        // S[i] here is always of type interface{}
        returnSlice = append(returnSlice, S[getRnd()]) // you need to implement getRnd() or just "math/rand" or something.
    }
    return returnSlice 
}

答案 1 :(得分:1)

编写一个与切片索引一起使用的示例函数。

// Sample k random elements from set of n elements.
// The function set sets an element in the output given 
// an index in the output and the index in the input.  
func sample(k int, n int, assign func(out int, in int)) {
    for i := 0; i < k; i++ {
        set(i, i)
    }
    for i := k; i < n; i++ {
        j := rand.Intn(i + 1)
        if j < k {
            set(j, i)
        }
    }
}

像这样使用:

in := []person{ {"John", 10}, {"Sally", 11}, {"James", 9}, {"Eve", 8} }
out := make([]person, 2)
sample(len(out), len(in), func(i, j int) { out[i] = in[j] })

因为sample仅适用于长度和索引值,所以它可以在任何类型的切片上使用。

此方法类似于标准库中的sort.Search