链接: https://play.golang.org/p/69I8PAuoAV
摘录:
package main
import "fmt"
type Stringer interface {
String() string
}
type fakeString struct {
content string
}
// function used to implement the Stringer interface
func (s *fakeString) String() string {
return s.content
}
func printString(value interface{}) {
switch str := value.(type) {
case string:
fmt.Println(str)
case Stringer:
fmt.Println(str.String())
}
}
func main() {
s := &fakeString{"Ceci n'est pas un string"}
printString(s)
printString("Hello, Gophers")
}
到达 case 时 printString(s)
函数调用与 case Stringer
部分匹配。
s
是类型 *fakeString
而不是 Stringer
。
为什么它匹配 Stringer
。
我做了一个 fmt.Println(reflect.TypeOf(str))
并确认类型为 *main.fakeString
最佳答案
在 Go 中,要满足一个接口(interface),你所要做的就是实现该接口(interface)的方法,别无其他。在这种情况下,要具有 Stringer 的行为,您必须实现 String() string
,因此 fakeString 类型的行为类似于 Stringer,因为实现那个方法;在 OOP 方面,我们使用接口(interface)来定义行为而不是类型或值。所以你可能整天都在不知不觉中实现 Go 接口(interface),但这没什么大不了的,只有当你必须满足行为时才重要。
实际上在一个真实的项目中,你可能想在 printString
方法中为你的开关添加一个 default
案例,以检测何时 interface{} 是其他东西,比如这个:
func printString(value interface{}) {
switch str := value.(type) {
case string:
fmt.Println("string", str)
case Stringer:
fmt.Println("Stringer", str.String())
default:
fmt.Printf("unexpected type: %T value: '%v'", str, str)
}
}
// main:
printString(2)
关于go - 为什么 switch 在下面的 golang 代码示例中匹配不同的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40702527/