2

在 Python 中,可以编写这样的代码,从列表中分配多个值:

(a, b, c, d) = [1,2,3,4]

切片是否有类似的 Go 库函数集?也就是说,我可以这样做: http ://play.golang.org/p/DY1Bi5omm1

package main

func get3(s []interface{}) (
    a interface{},
    b interface{},
    c interface{},
    rest []interface{}) {
  return s[0],s[1],s[2],s[4:]
}

func main() {  
  s := make([]interface{},5);
  for i :=0 ; i < 5; i++ { s[i] = i}
  a,b,c,_ := get3(s)

  print(a.(int))
  print(b.(int))
  print(c.(int))
}

有没有标准的 gophery 方法来做到这一点?

有没有办法绕过界面{}丑陋?

4

2 回答 2

2

不是这样的; 您将需要动态类型或参数多态性,这在 Go 中不可用。我能想到的最接近的是摆弄反射,如下所示:http ://play.golang.org/p/-K4jh2nZjq

// src is supposed to be []T.
// dst are supposed to be &T, except the last one, which must be a 'rest' &[]T (or nil for discarding).
// There must not be more dst vars than elements in src.
func extract(src interface{}, dst ...interface{}) {
    srcV := reflect.ValueOf(src)
    // Iterate over dst vars until we run out of them.
    i := 0
    for i = 0; i < len(dst)-1; i++ {
        reflect.Indirect(reflect.ValueOf(dst[i])).Set(srcV.Index(i))
    }

    // Now, the rest.
    restDst := dst[i]
    if restDst == nil {
        return
    }
    restV := reflect.ValueOf(restDst)
    indirectRest := reflect.Indirect(restV)
    l := srcV.Len() - i
    indirectRest.Set(reflect.MakeSlice(restV.Type().Elem(), 0, l))
    for ; i < srcV.Len(); i++ {
        itemV := srcV.Index(i)
        indirectRest.Set(reflect.Append(indirectRest, itemV))
    }
    return
}

然后你称之为:

sl := []int{1, 2, 3, 4, 5, 6} // int or any other type
var a, b, c int
var rest []int
extract(sl, &a, &b, &c, &rest)

所以丑出不去功能。

但请注意,所有这些都发生在运行时,因此它既不安全也不高效,而且绝对不是惯用的 Go。

于 2013-09-30T21:53:13.847 回答
2

我认为你不能,至少不能以惯用/干净的方式。您可以进行多项分配,但您必须直接或通过闭包传递单个值:

package main

import (
  "fmt"
)

func valuesFromList(list[]int,startFrom int) func() int  {
  i:=startFrom
  return func() int {
    ret := list[i]
    i++
    return ret
  }
}


func main () {
  list := []int{0,1,2,3,4,5,6,7,8,9}
  yield := valuesFromList(list,5)

  //This works
  a,b,c := yield(),yield(),yield()
  fmt.Println(a)
  fmt.Println(b)
  fmt.Println(c)

  //This also works
  d,e,f := list[0],list[1],list[2]
  fmt.Println(d)
  fmt.Println(e)
  fmt.Println(f)
  //This won't work
  //g,h,i:= list[7:9]
}
于 2013-09-30T21:58:16.837 回答