带读 |《Go in Action》(中文:Go语言实战)(二)接口

接口

接口的定义

这里用一个例子说明了golang中接口的含义与用法,先看代码

        // Launch the goroutine to perform the search.
        go func(matcher Matcher, feed *Feed) {
            Match(matcher, feed, searchTerm, results)
            waitGroup.Done()
        }(matcher, feed)

上面这段代码是search.go中调用Match函数的代码,其中Match的第一个参数“matcher”就是接口定义如下:

// Matcher defines the behavior required by types that want
// to implement a new search type.
type Matcher interface {
    Search(feed *Feed, searchTerm string) ([]*Result, error)
}

通过这个接口,我们的匹配器就可以用一致且通用的方法处理不同类型的匹配值,是不是很优雅

接口的命名

命名接口的时候,也需要遵守Golang的命名惯例。如果接口类型只包含一个方法,那么这个类型的名字以er结尾。我们的例子里就是这么做的,所以这个接口的名字叫作Matcher。如果接口类型内部声明了多个方法,其名字需要与其行为关联。

类实现接口

这里提供一个最简单的这个接口的类的实现

package search

type defaultMatcher struct {
}

func (m defaultMatcher) Search(feed *Feed, searchTerm string) ([]*Result, error) {
    return nil, nil
}

上面的代码有两点需要说明:
1.这个代码创建了一个类(defaultMatcher),这是一个空结构体,空结构体创建的时候系统不会分配任何内存,不需要维护状态,只需要实现接口即可,故,空结构体很适合创建没有任何状态的类型。
2.func 后面 Search前面的这个括号的内容是指定接收者,说白了就是把接下来要写的函数绑定在指定的类上,类似Java的成员方法。

接口方法调用受限

因为大部分方法在被调用后都需要维护接收者的值的状态,所以,一个最佳实践是,将方法的接收者声明为指针。对于defaultMatcher类型来说,使用值作为接收者是因为创建一个defaultMatcher类型的值不需要分配内存。由于defaultMatcher不需要维护状态,所以不需要指针形式的接收者。
与直接通过值或者指针调用方法不同,如果通过接口类型的值调用方法,规则有很大不同, 如代码清单2-38所示。使用指针作为接收者声明的方法,只能在接口类型的值是一个指针的时候被调用。使用作为接收者声明的方法,在接口类型的值为或者指针时,都可以被调用。


参考:Kennedy W , Ketelsen B , Martin E S . Go in action. 2016.

你可能感兴趣的:(go)