我正在学习Go
,文档和互动课程说空interface
可以包含任何类型,因为它不需要额外实现的方法。
举个例子:
func describe(i interace{}) {
fmt.Printf("Type: %T | Value: %v\n", i, i)
}
...会打印出来......
"Type: int | Value: 5" // for i := 5
"Type: string | Value: test" // for i := "test"
... etc
所以我想我的问题是,这是Go's
实现泛型函数的方法,还是有另一种更合适的方法。
答案 0 :(得分:3)
并不是说您现在就可以在生产中使用泛型(从2020年10月2日开始),但是对于对即将到来的go泛型功能感兴趣的人来说,最新的design draft是go,您可以编写泛型函数{ {1}}如下
Print
输出:
package main
import (
"fmt"
)
// T can be any type. Compilation will fail if T is not iterable.
func Print[T any](s []T) {
for _, v := range s {
fmt.Print(v)
}
}
func main() {
// Passing list of string works
Print([]string{"Hello, ", "world\n"})
// You can pass a list of int to the same function as well
Print([]int{1, 2})
}
答案 1 :(得分:2)
Go范例通常是通过在非空接口中实现行为来避免这种情况。例如,假设您想要打印具有特定类型格式的内容:
func Print(i interface{}) {
switch o := i.(type) {
case int64:
fmt.Printf("%5d\n", o)
case float64:
fmt.Printf("%7.3f\n", o)
case string:
fmt.Printf("%s\n", o)
default: // covers structs and such
fmt.Printf("%+v\n", o)
}
}
或者,您可以为知道自己如何串起来的事物定义一个接口(这在基础库中作为fmt.Stringer
存在),并使用它:
type Stringer interface {
String() string
}
func Print(o Stringer) {
fmt.Println(o.String())
}
type Foo struct {
a, b int
}
func (f Foo) String() string {
// Let's use a custom output format that differs from %+v
return fmt.Sprintf("%d(%d)", f.a, f.b)
}
type Bar struct {
t bool
}
func (b Bar) String() string {
if b.t {
return "TRUE! =D"
}
return "false =("
}
https://play.golang.org/p/Ez6Hez6cAv
这使您可以使用类似通用的功能,但仍保留类型安全性,并且行为本身由类型定义,而不是通用函数。
Go鼓励您以这种方式考虑类型,基于他们的行为,他们可以做什么而不是他们包含。
答案 2 :(得分:1)
Golang没有通用类型,所以你解决这个问题的方法是传递interface
类型并在函数中使用类型开关。