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 文档的痛点: 文档需 ...
随机推荐
- 我瞅瞅源码系列之---flask
快速使用 通过werkzurg 了解wsgi threading.local和高级 LocalStack和Local对象实现栈的管理 Flask源码之:配置加载 Flask源码之:路由加载 ...
- python学习-30 总结
小结 1.map函数: 处理序列中的每个元素,得到结果是一个‘列表’,该‘列表’元素个数及位置与原来一样 2.filter:遍历序列中的每个元素,判断每个元素得到的布尔值,如果是True则留下来,例如 ...
- JS实现简单的图片透明度循环变化(渐变)
找了好多,都是由100到0就结束了,到头来自己魔改,以下就是源码. div中加入img,js添加函数,完事(调用),取名后面加个1是为了避免冲突 <!DOCTYPE HTML> <h ...
- SQL Join连接大小表在前在后的重要性(小表在前提高执行效率)
引用地址:https://blog.csdn.net/qq_30349961/article/details/82662550 http://blog.sina.com.cn/s/blog_6ff05 ...
- 客开监控(BE/UI/BP)插件停用与启用
1.单据界面右键属性,获取当前客开监控页面URL连接:http://172.16.168.15/U9/erp/display.aspx?lnk=UFSoft.UBF.Cust.CustManager& ...
- HTTP响应状态
状态码分类 状态码详解 状态码 英文提示 说明 100 Continue 继续 101 Switching Protocols 切换协议.服务器根据客户端的请求切换协议.只能切换到更高级的协议,例如, ...
- Hive学习笔记(三)—— 数据类型
Hive的基本使用(一)--数据类型 1. Hive的基本数据类型 Hive数据类型 Java数据类型 长度 例子 TINYINT byte 1byte有符号整数 20 SMALINT short 2 ...
- eclipse创建springboot项目的三种方法
本文链接:https://blog.csdn.net/mousede/article/details/81285693 方法一 安装STS插件 安装插件导向窗口完成后,在eclipse右下角将会出现安 ...
- IEnumerable,ICollection,IList,List的使用
做C#的都知道:一类只能有一个继承类,但可以实现多个接口.这句话就告诉我们:IEnumerable,ICollection,IList,List区别了 首先我看看 IEnumerable: // ...
- np.newaxis的使用及有趣的数组相乘
a=np.array([1,2,3,4])a=a[np.newaxis,:] #固定行,相当于1行多列b=np.array([2,4,6]) b=b[:,np.newaxis] #固定列,相当与多行1 ...