Go 也有 接口( interface )的概念,它是一种特殊的类型,定义了一系列方法签名。其他任意类型,只要实现了接口声明的所有方法,就可以被视为接口类型,赋值给接口变量。
|
|
上面这个例子,MyFloat 和 *Vertex 都实现了接口 Abser ,因此可以被赋值给 Abser 类型的变量。
Go 也有 接口( interface )的概念,它是一种特殊的类型,定义了一系列方法签名。其他任意类型,只要实现了接口声明的所有方法,就可以被视为接口类型,赋值给接口变量。
|
|
上面这个例子,MyFloat 和 *Vertex 都实现了接口 Abser ,因此可以被赋值给 Abser 类型的变量。
Go 语言内置了不少接口定义,掌握这些接口用法可以写出更有 Go 范儿的程序!本节就带领大家,饱览最常用的几个:Stringer 、 error 以及 Reader 等等。
最常用的接口应该是 fmt 包里的 Stringer :
|
|
满足 Stringer 接口的数据类型,可以用一个字符串来描述自己,fmt 包依赖该接口打印数据。
通过 类型参数 ,Go 语言能够编写可以处理多种类型的函数。函数的类型参数位于参数列表前,以中括号括起来:
|
|
这个申明表示:s 是任意类型 T 的切片,x 是类型 T ,而 T 是一种内建约束 comparable ,代表任意可比较类型。
comparable 是一种很有用的类型约束,满足这种约束的类型 T 可以使用 ==
和 !=
运算符进行比较。下面这个例子,我们通过逐一比较,从切片元素中找出指定值。通过类型参数 T ,Index 函数可以支持任意可比较类型。
|
|
Go 语言提供了 goroutine 用于实现并发,这是一种轻量级线程,有时也叫做 协程 。
|
|
这行代码启动了一个新协程来执行函数调用:
|
|
请注意,函数参数 x 、y 和 z 求值由当前协程负责;而函数 f 的执行由新协程负责。
我们开发程序时,经常要对数据进行各种处理。如果用数学语言对数据处理操作进行抽象,可以归纳成以下操作:
开发 Go 程序,我们经常引用第三方模块。那么,怎么发布自己编写的模块呢?
请注意,一个版本打过标签发布后就不能再修改了。因为 Go 工具链用第一个下载副本来做验证,两个副本不同,就会报安全错误。与其修改先前发布版本的代码,不如发布一个新版本。
Go 模块代码通常采用 Git 来管理,代码仓库可以直接托管到 Github 上。为了演示 Go 模块的发布步骤,我在 Github 上建了一个极小化模块:fasionchan/goutils 。
代码仓库建好后还空空如也,我们先执行 go mod init
命令进行初始化(init 后面的参数是模块名):
|
|
该命令在当前目录下创建了 go.mod 文件,用来保存模块元数据,内容大致如下:
|
|
最近在开发一个通用消息通知工具,可以从 API 、数据库等数据源获取数据,然后根据数据渲染消息模板,然后通过企微、邮件、短信、电话语音等渠道推送消息。整个工作的设计思想,就是想提供一种低代码、配置化的消息通知解决方案。
简言之,工具对日常消息通知开发场景进行抽象建模,让所有要素都支持配置:
那在开发的过程中,就不可避免要面对数据提取问题。比如,有个系统提需求说他们的变更单需要每天催一次,列表通过 API 给我,结构如下:
|
|
本文先介绍一些 RESTful 理念 ,并通过一个 KVS 服务演示 RESTful API 的行为。最后以开发 KVS 服务为例,介绍如何使用 go-restful 框架编写 RESTful API 。
REST 是 Representational State Transfer 的缩写, 中文翻译是 表现层状态转换 。这种软件构建风格,通过基于 HTTP 之上的一组 约束 和 属性 ,提供万维网网络服务。其主要特点包括:
统一接口 是 RESTful 服务最大的特点。统一接口的核心思想是,将服务抽象成各种 资源 ,并通过一套一致、可预见的 URI 以及 请求方法( Request Method )来操作这些资源。这样一来,掌握了一种资源的使用方法,便可延伸到其他资源上,达到举一反三的效果。
Go 语言应用部署 不需要依赖 ,非常简便,这是一个不小的优势。
Go 语言官方镜像非常大,超过 500MB 。镜像之所以如此庞大是因为它包含了构建 Go 程序所需的全部 工具链 。然而运行编译好的(静态)二进制程序,并不需要这些工具。
本文介绍如何制作一个紧凑的 Docker 镜像用于部署 Go 应用,大小控制在 10MB 以内。
本文实验所有操作均在 macOS 下进行,在其他平台进行也是类似的。