为什么开关匹配golang中下面代码示例中的不同类型

为什么开关匹配golang中下面代码示例中的不同类型,go,switch-statement,Go,Switch Statement,链接: 摘录: 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 } f

链接:

摘录:

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
函数调用与
case Stringer
部分匹配。
s
属于
*fakeString
类型,而不是
Stringer
。 为什么它与Stringer匹配


我在Go中做了一个
fmt.Println(reflect.TypeOf(str))
,它确认了类型为
*main.fakeString

以满足一个接口,您所要做的就是实现该接口的方法,其他什么都不用做。在本例中,要使行为成为Stringer,您必须实现
String()String
,因此类型fakeString的行为是Stringer,因为实现了该方法;在OOP方面,我们使用接口只是定义行为,而不是类型或值。因此,您可能整天都在不知道的情况下实现Go接口,但这没什么大不了的,它只在您必须满足行为时才起作用

实际上,在实际项目中,您可能希望在方法
printString
中的开关中添加
default
大小写,以检测接口{}是否为其他对象,如下所示:

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中,要满足一个接口,您所要做的就是实现该接口的方法,而不是其他方法。在本例中,要使行为成为Stringer,您必须实现
String()String
,因此类型fakeString的行为是Stringer,因为实现了该方法;在OOP方面,我们使用接口只是定义行为,而不是类型或值。因此,您可能整天都在不知道的情况下实现Go接口,但这没什么大不了的,它只在您必须满足行为时才起作用

实际上,在实际项目中,您可能希望在方法
printString
中的开关中添加
default
大小写,以检测接口{}是否为其他对象,如下所示:

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)

这是歌朗的界面满意度

戈兰有两种类型:界面型和混凝土型

  • 具体类型
    的工作原理与您在
    开关
    中的预期完全相同:变量是给定类型的实例
  • 接口类型
    另一方面,它检查变量是否满足接口
哼,安全吗?它是如何工作的

如果(具体)类型具有接口所需的所有方法,则它满足接口。

--golang程序设计语言

在本例中,
Stringer
是一个接口,只声明一个方法:
String()String
。而
fakeString
通过拥有自己的
String()String
方法来满足它

但有两件事需要注意:

  • 具体类型可以有许多其他方法,如果它拥有接口中声明的所有方法,它仍然满足接口
  • 方法的顺序并不重要,重要的是方法的集合

  • 这是歌朗的界面满意度

    戈兰有两种类型:界面型和混凝土型

    • 具体类型
      的工作原理与您在
      开关
      中的预期完全相同:变量是给定类型的实例
    • 接口类型
      另一方面,它检查变量是否满足接口
    哼,安全吗?它是如何工作的

    如果(具体)类型具有接口所需的所有方法,则它满足接口。

    --golang程序设计语言

    在本例中,
    Stringer
    是一个接口,只声明一个方法:
    String()String
    。而
    fakeString
    通过拥有自己的
    String()String
    方法来满足它

    但有两件事需要注意:

  • 具体类型可以有许多其他方法,如果它拥有接口中声明的所有方法,它仍然满足接口
  • 方法的顺序并不重要,重要的是方法的集合

  • fakeString
    类型不等同于
    string
    ,但它确实实现了
    Stringer
    fakeString
    类型不等同于
    string
    ,但它确实实现了
    Stringer
    。谢谢。我花了一些时间才理解
    func(s*fakeString)String()String
    =
    fakeString
    实现
    Stringer
    。它似乎只是一个以类型为
    *fakeString
    s
    作为输入的函数。@Ivan与其他语言(如Java)不同,golang接口及其实现没有明确的代码声明,满足检查在后台运行。这可能会让初学者感到困惑!谢谢我花了一些时间才理解
    func(s*fakeString)String()String
    =
    fakeString
    实现
    Stringer
    。它似乎只是一个以类型为
    *fakeString
    s
    作为输入的函数。@Ivan与其他语言(如Java)不同,golang接口及其实现没有明确的代码声明,满足检查在后台运行。这可能会让初学者感到困惑!