Golang接口(Interface)的使用示例与代码分享 - https://play.golang.org/p/RKezV69HjPe

Golang接口(Interface)的使用示例与代码分享 - https://play.golang.org/p/RKezV69HjPe 链接

func bar(h human) {
switch h.(type) {
case person:
fmt.Println("I was passed into barrrrrr", h.(person).first)
case secretAgent:
fmt.Println("I was passed into barrrrrr", h.(secretAgent).first)
}
fmt.Println("I was passed into bar", h)
}

在这个函数中,没有接收器,对吗? (h human) 是参数吗? 为什么 secretAgent 的情况会在 person 的情况之前执行?

在运行过程中(不确定这个词是否准确),或者说当我运行它时,由于存在 “func (p person) speak() { fmt.Println(“I am”, p.first, p.last, " - the person speak”)",应该会有一行显示 “I am Dr. Yes - the person speak”。

// 转换
var x hotdog = 42
fmt.Println(x)
fmt.Printf("%T\n", x)
var y int
y = int(x)
fmt.Println(y)
fmt.Printf("%T\n", y)

语言规范 转换 = 类型 “(” 表达式 [ “,” ] “)” 。

我没有看到他的代码遵循语言规范中的格式

代码的哪部分产生了 “main.hotdog”,特别是 “main” 这部分

为什么 “fmt.Println(y)” 会输出 “42”,而它完全没有提到 “hotdog”


更多关于Golang接口(Interface)的使用示例与代码分享 - https://play.golang.org/p/RKezV69HjPe的实战教程也可以访问 https://www.itying.com/category-94-b0.html

10 回复

无法通过这种方式点击

更多关于Golang接口(Interface)的使用示例与代码分享 - https://play.golang.org/p/RKezV69HjPe的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是用于代码而非链接的。

谢谢。我刚刚重新研究了代码,现在理解得更透彻了。感谢您的帮助

这是方法的主体,但你并没有调用该方法

那程序员为什么要包含这个呢?

因为编写此代码的人希望 person 成为 human,而 human 要求实现者必须拥有 speak() 方法。

如果 person 没有该方法,就无法将其传递给 bar()

嗯。我会记住这一点的。我需要多加练习。

但是你从未调用过 p1.speak(),所以你没有指示程序实际打印那个内容。

我没有吗?我不是在这里调用了吗?

fmt.Println("I am", p.first, p.last, " - the person speak")

谢谢你

NobbZ:

能否请您使用围栏式代码块来高亮显示您的代码?

像这样吗?

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

这对我来说完全是新知识。这是我第一次听说它。

你可以在行首使用 > 来将引文标记为引用。

cherilexvold1974:

我不明白?我在这里没有吗?

fmt.Println("I am", p.first, p.last, " - the person speak")

这是方法的主体,但你并没有调用该方法。在你的代码中没有任何地方出现 p1.speak()

能否请您使用围栏代码块来高亮显示您的代码?

目前您的示例很难理解。

cherilexvold1974: 在这个函数中,没有接收器,对吗?

是的,没有。如果有的话,它就被称为"方法"。

cherilexvold1974: (h human) 是一个参数吗?

是的。

cherilexvold1974: 为什么 case secretAgent 在 case person 之前执行?

没有任何分支会"先于"另一个执行。Go 的 switch 结构总是只执行单个分支(除非使用 fallthrough)。

当您运行程序时,从整体来看而不仅仅是单个函数,前两次调用确实选择了 secretAgent 分支,因为您传入了 secretAgent。但说实话,您如何区分差异呢?两个分支会打印相同的内容。

cherilexvold1974: 在执行过程中(不确定这个词是否准确),或者当我运行它时,应该有一行显示"I am Dr. Yes - the person speak",因为"func (p person) speak() { fmt.Println(“I am”, p.first, p.last, " - the person speak")"

但您从未调用 p1.speak(),所以您从未指示程序实际打印该内容。

cherilexvold1974: 我不认为他的代码遵循语言规范中的格式

表达式 int(x)x 的值转换为 int 类型。int 是非终结符 Typex 是表达式。当然 () 需要按字面理解。

cherilexvold1974: 代码的哪部分导致了"main.hotdog",特别是"main"这个部分

是这一行:fmt.Printf("%T\n", x)main.hotdog 是您类型的限定名称。

如果您使用一些标签,会更容易识别哪行输出对应哪段代码:

fmt.Printf("Type of x: %T\n", x)

cherilexvold1974: 为什么"fmt.Println(y)“的结果是"42”,而它完全没有提到"hotdog"

因为 y 的值是 42,而不是 hotdog

以下是针对您提问的专业解答,基于您提供的代码和问题。

  1. 关于 bar 函数中的接收器和参数

    • bar(h human) 函数中,(h human) 是参数,而不是接收器。接收器仅出现在方法(method)定义中,例如 func (p person) speak() 中的 (p person) 是接收器,表示该方法属于 person 类型。bar 是一个普通函数,它接受一个 human 接口类型的参数 h
  2. 为什么 secretAgent 的情况在 person 之前执行

    • 在您提供的代码中,bar 函数使用类型开关(type switch)switch h.(type) 来检查 h 的具体类型。代码中 case person:case secretAgent: 的顺序取决于类型断言在开关中的排列。如果 secretAgent 的情况先执行,可能是因为在调用 bar 时传递的参数是 secretAgent 类型的实例,并且类型开关按代码顺序匹配第一个符合条件的 case。在 Go 中,类型开关按 case 顺序执行,一旦匹配就执行相应代码块并退出开关。因此,如果 hsecretAgent 类型,且 case secretAgent: 出现在 case person: 之前,它会先执行。示例代码中,如果 secretAgent 先定义或先被调用,可能导致此行为。但请注意,类型开关的顺序是固定的,由代码编写顺序决定。

    示例代码片段(基于您提供的上下文):

    type human interface {
        speak()
    }
    
    type person struct {
        first string
        last  string
    }
    
    func (p person) speak() {
        fmt.Println("I am", p.first, p.last, " - the person speak")
    }
    
    type secretAgent struct {
        person
        ltk bool
    }
    
    func (s secretAgent) speak() {
        fmt.Println("I am", s.first, s.last, " - the secretAgent speak")
    }
    
    func bar(h human) {
        switch h.(type) {
        case secretAgent: // 如果这个 case 在 person 之前,且 h 是 secretAgent 类型,会先执行
            fmt.Println("I was passed into barrrrrr", h.(secretAgent).first)
        case person:
            fmt.Println("I was passed into barrrrrr", h.(person).first)
        }
        fmt.Println("I was passed into bar", h)
    }
    
    func main() {
        sa := secretAgent{
            person: person{"James", "Bond"},
            ltk:    true,
        }
        bar(sa) // 这里会触发 secretAgent case,输出 "I was passed into barrrrrr James"
    }
    

    运行此代码,如果 bar(sa) 被调用,且 secretAgent case 在 person 之前,会输出 “I was passed into barrrrrr James”,然后调用 h.speak()(如果接口方法被调用)。

  3. 关于 “I am Dr. Yes - the person speak” 的输出

    • 在您提供的代码中,person 类型有一个 speak 方法:func (p person) speak() { fmt.Println("I am", p.first, p.last, " - the person speak") }。如果代码中创建了一个 person 实例并调用了 speak 方法,或者通过接口调用了它,就会输出该行。例如:
    p := person{"Dr.", "Yes"}
    p.speak() // 输出: I am Dr. Yes - the person speak
    

    bar 函数中,如果 hperson 类型,且调用了 h.speak(),也会输出。但您提供的 bar 函数中没有直接调用 speak,所以需要检查完整代码是否有其他调用。

  4. 关于类型转换和语言规范

    • 您提到的转换代码 var x hotdog = 42; y = int(x) 遵循 Go 语言规范。规范中转换的语法是 Type(Expression),这里 int(x) 是正确的,将 hotdog 类型(假设是 int 的别名)转换为 inthotdog 可能是一个自定义类型,例如 type hotdog int,因此转换是有效的。

    示例:

    type hotdog int
    var x hotdog = 42
    fmt.Println(x)        // 输出: 42
    fmt.Printf("%T\n", x) // 输出: main.hotdog
    var y int
    y = int(x)           // 转换 hotdog 为 int
    fmt.Println(y)       // 输出: 42
    fmt.Printf("%T\n", y) // 输出: int
    
  5. 为什么输出 “main.hotdog” 和 “42”

    • fmt.Printf("%T\n", x) 输出 main.hotdog,因为 x 的类型是 hotdog,而 hotdog 是在 main 包中定义的(假设代码在 main 包中)。main 是包名,表示类型定义的位置。
    • fmt.Println(y) 输出 42,因为 yint 类型,其值通过转换 int(x)x(值为 42)得来。转换过程丢弃了原始类型信息,只保留值,因此输出没有提到 “hotdog”。

总结:代码行为取决于类型定义、接口实现和调用顺序。如果您有完整代码,我可以进一步分析具体输出原因。

回到顶部