【问题标题】:Go: How to get length of slice in function?Go:如何在函数中获取切片的长度?
【发布时间】:2018-02-15 07:16:57
【问题描述】:

我有一个函数,我想向它提供不同类型的切片,然后我想循环它们并打印它们的内容。以下代码有效:

func plot(data interface{}){
    fmt.Println(data)
    //fmt.Println(len(data))
}

func main() {
    l := []int{1, 4, 3}
    plot(l)
}

但是当我取消注释打印切片长度的行时,我收到一条错误消息invalid argument data (type interface {}) for len

知道如何获取切片的长度以便循环遍历它吗?

【问题讨论】:

  • @CeriseLimón 根据问题“我想喂不同种类的切片”。
  • 如果参数是一个空接口,你必须使用reflect 包来做你想做的事。见golang.org/pkg/reflect。您可能需要考虑定义一个特定的接口,该接口定义了执行您需要对传入的对象执行的任何操作的方法。
  • 如果您正在使用不同类型的切片,您必须已经在使用反射或将它们断言到具体类型。你怎么使用data 却无法获得长度?
  • func plot (data interface{}, length int) 中传递长度不是更容易吗?在传递之前假设它不是interface{} 类型。

标签: arrays function go


【解决方案1】:

正如 cmets 中所暗示的,您必须使用反射来执行此操作,如下所示:

var sliceLen int

switch reflect.TypeOf(data).Kind() {

    case reflect.Slice:
        sliceLen = s.Len();
    default:
        //error here, unexpected
    }
}

虽然 go 在您需要时提供了反射来执行这些小技巧(以及许多其他用途),但通常最好尽可能避免维护编译器类型的安全性和性能,考虑拥有单独函数的利弊通过这种方法处理不同的数据类型

【讨论】:

    【解决方案2】:

    您应该尽可能避免使用 interface{}。你想做的事情可以通过反思来完成,但反思是必要的邪恶。它非常适合编组,但应谨慎使用。如果你仍然想使用反射,你可以这样做:

    func plot(data interface{}) {
        s := reflect.ValueOf(data)
        if s.Kind() != reflect.Slice {
            panic("plot() given a non-slice type")
        }
    
        for i := 0; i < s.Len(); i++ {
            v := s.Index(i)
            ...
        }
    }
    

    即使这样做了,v 还是一个reflect.Value。然后,您需要以某种方式将其转换为有用的东西。幸运的是,Value 有很多方法可以用来转换它。在这种情况下,v.Int() 会将值作为 int64 返回。

    【讨论】:

      猜你喜欢
      • 2015-02-23
      • 2016-02-24
      • 1970-01-01
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 2015-05-07
      • 2019-12-22
      相关资源
      最近更新 更多