Golang 结构不满足方法 return 类型中的接口要求

Golang struct not fulfilling interface requirement in method return type

我有一个简单的方法可以将字符串写入文件,如下所示:

type IFile interface {
    WriteString(s string) (n int, err error)
}

func writeStrToFile(createFile func(string) (IFile, error), data string) {
    file, _ := createFile(getFilePath())
    file.WriteString(data)
}

假设 getFilePath() return 是当前 OS

的有效文件路径字符串

我尝试使用以下方法调用函数 writeStrRefreshTokenToFile()

writeStrToFile(os.Create, "DATA")

据我了解,os.Createfunc(name string) (*os.File, error) 的 return 方法签名应该满足 writeStrToFilefunc(string) (IFile, error) 的参数类型要求,因为 *os.File 应该是接口 IFile 的有效实现。但是,在实现中我得到一个 IncompatibleAssign 错误。这是为什么?


上下文:
最终,我正在尝试为此函数编写单元测试,以便我可以预期 createFile()WriteString() 函数被正确调用。我是 Go 的新手,所以我可能只是在接近这个错误并且不需要如此彻底地测试函数的实现。但是,没有 return 值,否则该函数似乎无法测试

错误消息告诉您 type func(name string) (*os.File, error) 不能用作 type func(string) (IFile, error)。函数签名不同:*os.FileIFile 是不同的类型。

假设 Go 按您的预期工作,还有另一个问题。该程序泄露了从 os.Create.

返回的文件描述符

另一种构造代码的方法是这样的:

func writeStrToFile(writeFile func(name string, data []byte, perm FileMode) error, data string) {
    writeFile(getFilePath(), []byte(data), 0666)
}

通常这样调用:

writeStrToFile(os.WriteFile, "DATA")

将os.WriteFile替换为另一个函数进行测试。

问题是:

当您需要定义函数签名时,所有参数和return类型应该完全相同

func() A != func() B

即使B是A实现的接口。类型别名除外。

快速解决方案是添加一个包装器以从一种类型转换为另一种类型

wrapper := func(path string) (IFile, error){
    return createFile(path)
}

f, err := wrapper(…)