带读 |《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.

0 条评论
请不要发布违法违规有害信息,如发现请及时举报或反馈
还没有人评论呢,速度抢占沙发!
相关文章
  • 今日记录一下 学习 golang 这门语言遇到的一些比较特殊的细节,供大家参考。    所以,在我们输出内容的时候,可以包含很多的非 ASCII 码字符。实际上,Go 是天生支持 UTF...

  • 文章字数大约1.95万字,阅读大概需要65分钟,建议收藏后慢慢阅读!!! 1. GoLang语言 1.1 Slice Slice底层实现原理 切片是基于数组实现的,它的底层是数组,它自己本身非常小...

  • 最近做的一个项目是采用前后端分离模式写前端,后端是fabric区块链,提供接口,需要使用post方法进行访问。如上一章注册用户,就是需要把用户名、账户信息转换成json形式 使用post方法传给后端区...

  • 我的客服系统使用的Golang+ Gin作为后端服务,所以下面的代码是演示demo 在 Go 语言中使用 Gin 框架实现 WebSocket 的方法如下: 安装 gin-gonic/websoc...

  • 概述建议先阅读 函数 和 接口 小节。例子errors.New() 创建错误package main import ( "errors" "fmt" ) // 自定义除法函数 fu...

  • 示例代码package main // 包名,必须声明 func main() { println("hello world") }Go 代码组织方式Go 代码是使用包来组织的,类似于...

  • 前言随着时间的推移,语言爱好者已经构建和共享了许多 Go 框架和库。这些包执行不同的功能,从开发微服务到制作 discord 机器人,一直到构建 Web 应用程序!在本文中,我将尝试让您熟悉一些有用的...

  • 前言上一篇文章我们介绍了ProtoBuf的使用,不了解ProtoBuf的同学建议先读这篇文章:# 一文带你玩转ProtoBuf,会用protobuf是学习gRPC的基础。之前我也有写过RPC相关的文章...

  • msf生成的裸马现在已经不行了,加壳也只能加冷门壳了,VMP,Shielden,upx不是失效就是效果很差,所以当下,得用shellcode来免杀了 msfvenom -a x86 --platfo...

  • 对于无类型常量,可能大家是第一次听说,但这篇我就不放进拾遗系列里了。 因为虽然名字很陌生,但我们每天都在用,每天都有无数潜在的坑被埋下。包括我本人也犯过同样的错误,当时代码已经合并并发布了,当我意识到...

  • hello 大家好呀,我是小楼,这是系列文《Go底层原理剖析》的第三篇,依旧分析 Http 模块。我们今天来看 Go内置的 RPC。说起 RPC 大家想到的一般是框架,Go 作为编程语言竟然还内置了 ...

  • 一 jaeger链路追踪介绍 什么是链路追踪: 分布式链路追踪就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的...

  • 所有人都听过这样一个歌谣:从前有座山,山里有座庙,庙里有个和尚在讲故事:从前有座山。。。。,虽然这个歌谣并没有一个递归边界条件跳出循环,但无疑地,这是递归算法最朴素的落地实现,本次我们使用Golang...

  • 概述Map 是一种键值对的无序集合,在其他编程语言中也被称为 字典, Hash, 关联数组。重要的一点是: Map 键 的数据类型必须是可以比较的,例如 string, int, float64,类型...

  • initinit内容本书推荐将map映射(或者叫注册)之类的准备工作放在init里面,Golang会保证init中的函数在main函数调用之前执行完毕。例如:// init registers the...

  • 首先引用一句名言: Don’t communicate by sharing memory; share memory by communicating. (不要通过共享内存来通信,...

  • 任何一门编程语言都离不开对各种工具包的使用,工具包的管理就显得异常重要了。Go 的包管理方式是逐渐演进的,本文介绍Go语言的两种包管理模式。 GOPATH模式引包(不推荐) 在 1.5 版本之前,所...

  • 1. 前言 所谓的逃逸分析(Escape analysis)是指由编译器决定内存分配的位置吗不需要程序员指定。 函数中申请一个新的对象 如果分配在栈中, 则函数执行结束后可自动将内存回收 如果分配...

  • 一 JWT介绍 JWT 英文名是 Json Web Token ,是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范,经常用在跨域身份验证。 JWT 以 JSON 对象的形式安全传...

  • 概述调用 sync/atomic 包即可。错误的并发操作先来看一个错误的示例。通过启动 1000 个 goroutine 来模拟并发调用,在函数内部对变量 number 进行自增操作,那么可能存在的一...