go 学习 (四):接口 & 方法
接口声明
// 接口声明 语法:接口是一个 函数签名 的集合,函数签名(函数的声明,不包括实现)
type interfaceName interface {
method1(param paramType, param paramType...) (returnName returnType ...)
method2(param paramType, param paramType...) (returnName returnType ...)
} // 接口名一般加 er
type writer interface {
write(num int) (n int, flag bool)
cache(p []byte) int
}
// 若方法名首字母是大写时,且接口名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。 // 声明结构体
type structName struct {
filed1 filedType
filed2 filedType
} // 实现接口中的方法
func (structVariableName structName) method1 (param paramType, param paramType...) (returnName returnType returName returnType, ...) {
// do something
} func (structVairableName structName) method2 (param paramType, param paramType...) (returnName returnType, returnName returnType,...) {
// do something
} // 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以被忽略 // 实例
type Phone interface {
call(number int) string
} // 定义结构体
type Apple struct {
name string
} type Sony struct {
name string
}
// 实现方法
func (appleBanner Apple) call(number int) string {
fmt.Println("param number: ", number)
fmt.Println("banner name: ", appleBanner.name)
return "successful"
} func (sonyBanner Sony) call(number int) string {
fmt.Println("param number: ", number)
fmt.Println("banner name: ", sonyBanner.name)
return "successful"
} func main() {
var apple = Apple{"apple"}
apple.call() sony := Sony{"sony"}
sony.call()
}
实现接口的条件
- 接口中的方法签名包括:方法名称、方法所需参数、参数类型、方法的返回值、返回值类型;若需要实现接口中的某个方法签名,其上述的五个要点需全部保持一致。
- 接口被正确的编译使用需要 实现接口中的全部方法
类型与接口、接口与接口
- 一个类型可以实现多个接口,比如一个 socket 结构体同时实现了 io接口和日志接口。
- 多个类型可以实现相同的接口 ,一个结构体可以嵌套另一个结构体,若一个接口有多个方法需要实现,可以某个结构体实现其中几个方法,剩下的方法由另一个结构体实现。
// 包含 开启方法和写日志方法 的服务接口
type Service interface {
Start() // 开启服务
Log(string) // 日志输出
} // 日志器
type Logger struct {
} // 日志结构体 实现 Log()方法
func (g *Logger) Log(l string) {
} // 游戏服务
type GameService struct {
Logger // 嵌入日志器
} // 游戏结构体 Start()方法
func (g *GameService) Start() {
} // 使用
var s Service = new(GameService)
s.Start()
s.Log(“hello”)
- 一个接口同时包含了多个其他接口,产生了一个新的接口
// 写入接口
type Writer interface {
Write(p []byte) (n int, err error)}
// 关闭接口
type Closer interface {
Close() error
} // 接口嵌套
type Logger interface { // 此接口需要两个接口嵌入
Writer
Closer
}
排序接口
package main import (
"fmt"
"sort"
) // 自定义类型 排序
type Interface interface {
Len() int // 序列内元素数量
Less(i, j int) bool // 序列中 索引为i的元素 < 索引为j的元素
Swap(i , j int) // 交换两个索引上的元素
} // 将字符串定义成 自定义类型 (type 关键字)
type MyStringList []string // []string: 字符串切片; 为了能对自定义的字符串切片排序,需要让 MyStringList 实现 Interface 接口 // 方法
func (stringLists MyStringList) Len() int {
return len(stringLists)
} func (stringLists MyStringList) Less(i, j int) bool {
return stringLists[i] < stringLists[j]
} func (stringLists MyStringList) Swap(i, j int) {
stringLists[i], stringLists[j] = stringLists[j], stringLists[i]
} // 结构体排序
type HeroKind int // 英雄的种类
const ( // 定义 HeroKind 的 value 为常量, 类似枚举
None HeroKind = iota
Tank
Assassin
Mage
) type Hero struct { // 定义英雄的结构
Name string // 英雄名字
Kind HeroKind // 英雄种类
} type Heros []*Hero // 英雄切片集合
// 实现 Interface 接口的三个方法
func (heros Heros) Len() int {
return len(heros)
} func (heros Heros) Less(i, j int) bool {
if heros[i].Kind != heros[j].Kind { // 两个英雄的种类不一致时, 优先的按照 种类数字大小进行对比, 否则 则按照英雄名字对比
return heros[i].Kind < heros[j].Kind
}
return heros[i].Name < heros[j].Name
} func (heros Heros) Swap(i, j int) {
heros[i], heros[j] = heros[j], heros[i]
} // 对切片元素进行排序: sort.Slice() func main() {
// 1、自定义类型实现排序
names := MyStringList {
"3. Triple Kill",
"5. Penta Kill",
"2. Double Kill",
"4. Quadra Kill",
"1. First Blood",
}
fmt.Println(names)
sort.Sort(names) // 排序:sort.Interface 用于指定 通用排序算法 和 可能被排序到的序列类型 之间的规定
fmt.Println(names) // 2、sort 包中的便捷排序
//names := sort.StringSlice { // 字符串切片 排序
// "3. Triple Kill",
// "5. Penta Kill",
// "2. Double Kill",
// "4. Quadra Kill",
// "1. First Blood",
//}
//fmt.Println(names)
//sort.Strings(names)
//fmt.Println(names) //nums := sort.IntSlice { // 整型切片 排序
// 10,
// 1,
// 6,
// 5,
// 2,
//}
//fmt.Println(nums)
//sort.Ints(nums)
//fmt.Println(nums) //doubles := sort.Float64Slice{ // 双精度小数切片 排序
// 5.02,
// 3.31,
// 10.19,
// 2.20,
// 12.12,
// 6.18,
// 1.12,
//}
//fmt.Println(doubles)
//sort.Float64s(doubles)
//fmt.Println(doubles) // 3、结构体排序
heros := Heros{
&Hero{"吕布", Tank},
&Hero{"李白", Assassin},
&Hero{"妲己", Mage},
&Hero{"貂蝉", Assassin},
&Hero{"关羽", Tank},
&Hero{"诸葛亮", Mage},
}
fmt.Println("排序前结构体顺序: ")
for index, hero := range heros {
fmt.Print(index, "\t")
fmt.Println(*hero)
} //sort.Sort(heros) // 4、对切片元素排序: sort.Slice(slice interface{}, less func(i, j int) bool) {...}
sort.Slice(heros, func(i, j int) bool { // 传入 切片 和 在排序时对元素进行判断的回调函数
if heros[i].Kind != heros[j].Kind {
return heros[i].Kind < heros[j].Kind
}
return heros[i].Name < heros[j].Name
})
fmt.Println()
for index, hero := range heros {
fmt.Print(index, "\t")
fmt.Println(*hero)
} }
go 学习 (四):接口 & 方法的更多相关文章
- go微服务框架go-micro深度学习(四) rpc方法调用过程详解
上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取server的地 ...
- Struts2学习四----------动态方法调用
© 版权声明:本文为博主原创文章,转载请注明出处 Struts2动态方法调用 - 默认:默认执行方法中的execute方法,若指定类中没有该方法,默认返回success <package nam ...
- Android JNI 学习(四):接口方法表 & Base Api & Exception Api
本文我们来总结一下JNI 提供的功能列表及相关的函数表. 注意:请注意使用术语“必须”来描述对JNI程序员的限制.例如,当您看到某个JNI函数必须接收非NULL对象时,您有责任确保不将NULL传递给该 ...
- C# 你什么让程序员寂寞成酱紫 (男生版 娱乐中学习 抽象类 接口 继承 实现方法 )
你什么让程序员寂寞成酱紫 (男生版 娱乐中学习 抽象类 接口 继承 实现方法 ) 一个家庭 相当于 一个空间,这个空间里 有 很多元素,比如 爱,爱这个抽象事物,可能有很多动作,接吻.交流,对于一 ...
- PHP学习笔记,curl,file_get_content,include和fopen四种方法获取远程文件速度测试.
这几天在做抓取.发现用PHP的file_get_contents函数来获取远程文件的过程中总是出现失败,并且效率很低下.所以就做了个测试的demo来测试下PHP中各种方法获取文件的速度. 程序里面使用 ...
- 详解PHP的__set()、__get()、__isset()、unset()四个方法
PHP系统中给我们提供了很多预定义的方法,这些方法大部分都需要在类中声明,只有需要时才添加到类中.它们的作用.方法名称.使用的参数列表和返回值都是在PHP中预定好的,并且都是以两个下划线开始的方法名称 ...
- Android JNI学习(四)——JNI的常用方法的中文API
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- (转)SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合
http://blog.csdn.net/yerenyuan_pku/article/details/72231763 之前我整合了Spring和MyBatis这两个框架,不会的可以看我的文章MyBa ...
- Spring Boot 项目学习 (四) Spring Boot整合Swagger2自动生成API文档
0 引言 在做服务端开发的时候,难免会涉及到API 接口文档的编写,可以经历过手写API 文档的过程,就会发现,一个自动生成API文档可以提高多少的效率. 以下列举几个手写API 文档的痛点: 文档需 ...
随机推荐
- Spark学习(2) RDD编程
什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.弹性.里面的元素可并行计算的集合 RDD允 ...
- Python2 和 Python3区别
字符串类型不同 py3: str bytes py2: unicode str 默认解释器编码 输入输出 int int long 除法 range和xrang 模块和包 字典 keys py2:列表 ...
- 去除Chrome“请停用以开发者模式运行的扩展程序”提示
将version.dll放在chrome同级目录,重启浏览器( 79.0.3945.79版本后已失效)
- 关于nslookup以及dig命令的研究报告
我们在日常上网时都是用域名访问网路,如www.baidu.com,而在实际寻址过程中,是使用IP地址,如180.101.49.11,域名到IP地址的解析是通过DNS服务器来实现的,系统中我们可以用一些 ...
- 「UER#2」谣言的传播
「UER#2」谣言的传播 写了个乱搞,怎么莫名其妙就AC了,这...,之后又想了30min结合题解终于会证了. 首先最大值比较简单,记 \(f_i\) 为第 \(i\) 个点能到达的点数,上界 \(\ ...
- UOJ424 Count 生成函数、多项式求逆、矩阵快速幂
传送门 两个序列相同当且仅当它们的笛卡尔树相同,于是变成笛卡尔树计数. 然后注意到每一个点的权值一定会比其左儿子的权值大,所以笛卡尔树上还不能够存在一条从根到某个节点的路径满足向左走的次数\(> ...
- CentOS7 搭建 NFS 服务器
环境: 系统版本:CentOS 7.5 一.服务端配置 1.配置环境 关闭防火墙服务 # 停止并禁用防火墙 $ systemctl stop firewalld $ systemctl disable ...
- Linux学习笔记之tail命令显示最后n行
tail :输出文件的最后几行. 用于linux查看日志的时候很方便,假如日志文件为:Console.log用法:1. tail Console.log tail # 输出文件最后10行的内容 2. ...
- 把项目通过maven生产源码包和文档包并发布到自己的私服上
<!-- 把项目通过maven生产源码包和文档包并发布到自己的私服上 执行maven命令,mvn clean package,执行完成后 命令:mvn deploy 就可以发布到你自己的私服上了 ...
- 如何让 height:100%; 起作用---父级元素必须设定高度
参考: http://www.webhek.com/post/css-100-percent-height.html https://www.cnblogs.com/kunmomo/p/1060066 ...