go - 接受任何 slice 的 Express 函数

标签 go types

我想表达一个可以接受任何 slice 的函数。我认为我可以做到这一点:

func myFunc(list []interface{}) {
  for _, i := range list {
    ...
    some_other_fun(i)
    ...
  }
}

其中 some_other_fun(..) 本身采用 interface{} 类型。但是,这不起作用,因为您不能将 []DEFINITE_TYPE 作为 []interface{} 传递。请参阅:https://golang.org/doc/faq#convert_slice_of_interface其中指出 []interface{} 的表示是不同的。这个答案总结了为什么但是关于接口(interface)指针而不是接口(interface) slice ,但原因是一样的:Why can't I assign a *Struct to an *Interface? .

上面 golang.org 链接中提供的建议建议从 DEFINITE_TYPE slice 重建一个新的接口(interface) slice 。然而,在我想调用这个函数的代码中的任何地方这样做并不实际(这个函数本身意味着只缩写 9 行代码,但这 9 行在我们的代码中出现得相当频繁)。

在我想调用函数的每一种情况下,我都会传递一个 []*DEFINITE_TYPE,我起初认为它更容易抽象,直到我再次发现 Why can't I assign a *Struct to an *Interface? (也在上面链接)。

此外,每次我想用不同的 DEFINITE_TYPE 调用函数时,因此为 n 个类型实现 n 个示例不会为我节省任何代码行或使我的代码更清晰(相当相反!)。

令人沮丧的是我不能这样做,因为这 9 行代码在我们的代码中是惯用的,而且输入错误很容易引入错误。我真的很想念泛型。真的没有办法吗?!!

最佳答案

在您提供的情况下,您必须将 slice 创建为 interface 的 slice ,例如s := []接口(interface){}{}。在这一点上,您可以从字面上将任何您想要的类型放入 slice 中(甚至混合类型)。但随后您将不得不进行各种类型断言,一切都变得非常糟糕。

解码器常用的另一种技术是这样的定义:

func myFunc(list interface{})

因为 slice 适合接口(interface),所以您确实可以将常规 slice 传递给它。您仍然需要在 myFunc 中执行一些验证和类型断言,但您将对整个列表类型执行单个断言,而不必担心可能包含混合类型的列表。

无论哪种方式,由于是静态类型语言,您最终必须知道通过断言传入的类型。事情就是这样。在你的情况下,我可能会使用上面的 func 签名,然后使用类型开关来处理不同的情况。请参阅此文档 https://newfivefour.com/golang-interface-type-assertions-switch.html

所以,像这样:

func myFunc(list interface{}) {
    switch v := list.(type) {
        case []string:
            // do string thing
        case []int32, []int64:
            // do int thing
        case []SomeCustomType:
            // do SomeCustomType thing
        default:
            fmt.Println("unknown")
    }
}

关于go - 接受任何 slice 的 Express 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42987535/

相关文章:

docker - 无法启动服务应用程序 : OCI runtime create failed: container_linux. go:349

java - 单精度和 double 浮点值有什么不同?

c++ - 根据大小扣除类型 C++

Python 数据类型

go - 如何解释 os.FileMode 的显示值?

Go Stdin Stdout 通信

go - gouuid 在 V5 上会始终生成相同的值吗

url - 在 Go 中转换相对于绝对 URL

sql-server - Entity Framework 将 SQL Server tinyint 映射到 Int16

sql-server - SQL Server 文本数据类型最大长度 = 65,535?