我正在学习中Go
,文档和交互式课程说,空interface
可以容纳任何类型,因为它不需要其他实现的方法。
举个例子:
func describe(i interface{}) {
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
实现通用函数的方法,还是还有另一种更合适的方法来实现它们。
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
这使您具有类似泛型的功能,但仍保留类型安全性,并且行为本身 由type 定义,而不是 由 泛型函数定义。
Go鼓励您以这种方式根据类型的行为,可以 做什么 而不是 包含的内容 来思考类型。
问题内容: 最近,人们对Go提出了很多批评,因为它不支持泛型。这到底是什么意思呢?您如何向不熟悉这种动态类型语言(如Ruby)的人解释这一点? 问题答案: 在动态类型语言中,您不必关心列表是什么类型,而只是列表。但是,在静态类型的语言中,您确实在意列表的类型,因为类型是“ A的列表”,其中“ A”是某种类型。也就是说,a 与的类型不同。 因此,当您谈到泛型时,调用类型为列表中每个项目的某个函数时,
同样的规则也可以适用于函数:在使用前给出 <T> 后,类型 T 就变成了泛型。 使用泛型函数有时需要显式地指明类型参量。这种可能的情况包括,调用返回类型是泛型的函数,或者编译器没有足够的信息来推导类型参量。 函数调用使用显式指定的类型参量,如下所示: fun::<A, B, ...>(). struct A; // 具体类型 `A`。 struct S(A); //
我想实现一个简单的排序函数,排序列表并返回排序列表(非常容易!)。所以我写了这个 问题是,当我试图对一个简单的列表排序时,它会给我带来这样的错误 那有什么问题?! 提前感谢:)))
问题内容: 免责声明:我现在只和Go玩了一天,所以我很有可能错过了很多。 有谁知道为什么Go中没有对泛型/模板/ whatsInAName的真正支持?因此,有一个通用的,但这是由编译器提供的,而Go程序员无法编写自己的实现。关于如何使Go尽可能正交的所有讨论,为什么我可以使用通用类型而不创建新类型? 尤其是在函数式编程方面,有lambda甚至闭包,但是在缺少泛型的静态类型系统中,我该如何编写泛型高
我不想为每个类型T编写这个方法只是为了调用getMessage()并将其传递给下一个方法。 有可能写出这样的方法吗?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T(如字符串getMessage())。
我试图从我的程序中创建的go例程中捕捉崩溃/恐慌,以便将它们发送到我的崩溃错误报告服务器(如Sentry/Raygun) 例如, 做这件事的惯用方法是什么?