什么时候以及为什么在Golang中返回接口



示例代码:

type IClient interface {
UploadFile(sourcePath, host string) error
CopyFile(sourcePath, destPath string) error
DeleteFile(sourcePath, option string) error
GetChecksum(sourcePath string) (*string, error)
GetSize(sourcePath string) (*float32, error)
}
type FileWorker struct {
Extension string
Host string
}
func NewFileWorker(fileExtension, host string) IClient {
var fileWorker = &FileWorker {
Extension: extension,
Host: host,
}
return fileWorker
}
//NOTE: type FileWorker is the receiver of all methods implementing the IClient interface

我见过其他";新的";(或"Get"(函数返回接口。但它实际上并没有返回接口,而是返回一个实现所述接口的结构。反过来,该结构类型是实现所述接口的各种方法的接收器。

问题:我们何时以及为什么返回接口?目前,我认为这是一种迂回的做事方式,导致在试图理解一些代码的同时,必须追溯多个文件。

接口是实现代码重用的一种方式。通常情况下,重要的不是物体是什么,而是它的作用。考虑以下方法:

func Grade(questions []MultipleChoiceQuestion) {
total := len(questions)
correct := 0
for _, q := range questions {
if q.Test() {
correct++
}
}
return correct / total
}

函数Grade接收一组问题并对用户的答案进行评分。

如果我们想添加正确或错误的问题呢?现在Grade只接受MultipleChoiceQuestions,这意味着我们必须制作一个全新的函数,比如GradeTrueOrFalse(questions []TrueOrFalseQuestions),才能用真问题或假问题进行测试。此外,我们将无法进行由多项选择题和真题或假题组成的测试。

然而,我们应该能够在一次测试中组合问题。原来的函数并不关心它是什么样的问题,只关心这个问题可以测试((用户的答案。这就是接口的用武之地

通过将Test方法抽象为一个接口,我们可以对任何类型的问题使用Grade

type Tester interface {
Test() bool
}
type MultipleChoiceQuestion struct
func (q MultipleChoiceQuestion) Test() bool {
// implementation...
}
type TrueOrFalseQuestion struct
func (q TrueOrFalseQuestion) Test() bool {
// implementation...
}
func Grade(questions []Tester) {
total := len(questions)
correct := 0
for _, q := range questions {
if q.Test() {
correct++
}
}
return correct / total
}

现在Grade可以回答任何问题。此外,questions []Tester可以是多选题和对错题的混合。

如果使用得当,您应该很少需要执行类型断言或";通过多个文件回溯";了解发生了什么。

最新更新