go - 为什么 switch 在下面的 golang 代码示例中匹配不同的类型

标签 go switch-statement

链接: 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)

https://play.golang.org/p/pmxSXfUu4e

关于go - 为什么 switch 在下面的 golang 代码示例中匹配不同的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40702527/

相关文章:

vue.js - 如何同时使用 Vue-Router 和 Gorilla Mux 路由器

default - switch 语句是否应该始终包含 default 子句?

c - 将 switch/case 与 malloc() 一起使用

java - Java switch-case 语句中不区分大小写的匹配

c - 为什么下面的代码给出了第一个手机号码。不论名字

在 GoLang 中用于后缀检测的正则表达式

arrays - 解析 JSON 对象的 JSON 数组?

go - 将字符串时间转换为int

arrays - 接近 'How many items do you have selected' 类型计数器的最佳方法是什么?

c - 如何使用 GO 导入用 C 编写的 DLL 函数?