Golang中为什么程序方法会被隐式调用?求建议

Golang中为什么程序方法会被隐式调用?求建议

我买了一本新的Go语言书籍,但被书中的一个小示例程序卡住了。基本上,我不理解为什么这个方法会被自动调用和执行。根据我在网上看到的其他示例,如果要使用一个方法,实际上需要主动调用它。示例程序在这个链接[Go语言游乐场](https://play.golang.org/p/PhdSsbzXcbE)。方法'func (a *AngryReader) Read(b []bye)'不知何故被调用了,我实在无法理解。如果能得到任何帮助,我将不胜感激。

提前感谢。
func main() {
    fmt.Println("hello world")
}

更多关于Golang中为什么程序方法会被隐式调用?求建议的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

嗨,Joe,这个函数并不是自动运行的,实际情况是当你将 AngryReader 作为参数调用 ioutil.ReadAll 时,ioutil.ReadAll 本身会调用 AngryReader 的 Read 函数。

更多关于Golang中为什么程序方法会被隐式调用?求建议的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


NobbZ,

非常感谢您如此迅速的回复。我觉得在书中读过非常相似的内容,并且毫无疑问您的回答是真实且正确的。然而,由于我不是程序员,我很难理解它。您能否重新措辞您的回答,或者给我指出一些在线的文档,可能更适合初学者?无论如何,感谢您的时间和帮助。

Joe

我的帖子中有链接,这些链接加上完成Go语言之旅应该足以理解。

最简单的答案就是:"ReadAll"会调用你传入的任何对象的Read方法。

func main() {
    fmt.Println("hello world")
}

ioutil.ReadAll()io.Reader 接口的包装器。

任何实现了 Read(p []byte) (n int, err error) 方法的类型都被视为实现了该接口,这就是为什么可以将 AngryReader 传递给 ReadAll 的原因。该函数随后会持续调用参数的 Read 方法,直到遇到 EOF 为止,并将读取的字节作为单个切片返回。

在Go语言中,方法被隐式调用通常发生在实现了特定接口的情况下。根据您提供的代码片段,虽然main函数非常简单,但您提到的AngryReader类型很可能实现了io.Reader接口,而该接口的Read方法在特定上下文中会被自动调用。

例如,当您将AngryReader实例传递给期望io.Reader参数的函数时(如io.Copyioutil.ReadAll),Go运行时会自动调用其Read方法。这是因为Go的接口机制允许类型通过实现接口方法来自动满足接口要求,并在需要时触发这些方法的执行。

以下是一个示例,说明Read方法如何被隐式调用:

package main

import (
    "fmt"
    "io"
    "strings"
)

// 定义AngryReader类型
type AngryReader struct {
    src io.Reader
}

// 实现io.Reader接口的Read方法
func (a *AngryReader) Read(b []byte) (int, error) {
    n, err := a.src.Read(b)
    for i := 0; i < n; i++ {
        if b[i] >= 'a' && b[i] <= 'z' {
            b[i] = b[i] - 'a' + 'A' // 将小写字母转换为大写
        }
    }
    return n, err
}

func main() {
    src := strings.NewReader("hello world")
    reader := &AngryReader{src: src}
    
    // 使用io.Copy时,Read方法会被自动调用
    _, err := io.Copy(io.Discard, reader)
    if err != nil {
        fmt.Println("Error:", err)
    }
}

在这个示例中,AngryReader实现了io.Reader接口的Read方法。当io.Copy函数被调用时,它会反复调用readerRead方法,直到遇到io.EOF错误。这就是Read方法被隐式调用的原因:它通过接口被系统库函数触发,而不是在您的代码中直接调用。

如果您在原始代码中使用了类似io.Copybufio.NewReader或任何其他接受io.Reader的函数,就会导致Read方法自动执行。检查您的完整代码,确认是否有将AngryReader实例传递给这类函数的情况。

回到顶部