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 文档的痛点: 文档需 ...
随机推荐
- Linux下Ngnix的安装与配置
由于我的博客项目在8084端口,需要Nginx来转发一下端口,记录一下安装过程和踩过的小坑. 一.下载 wget http://nginx.org/download/nginx-1.12.2.tar. ...
- 用NDK生成cURL和OpenSSL库
最近在用Qt开发Android应用时需要获取https页面内容,但Qt内置的QNetworkAccessManager类只支持下面这些协议(调用其supportedSchemes成员函数获取): (& ...
- STVD使用printf输出数据错误
使用STM8L052输出调试信息 重定向put char #include "stdio.h" //必不可缺少 char putchar (char c) { /* Write a ...
- 【LEETCODE】71、验证二叉树的前序序列化
简单粗暴,代码有待优化,不过自己独立完成,没有参考任何材料,还是比较满意的 package y2019.Algorithm.stack.medium; import java.util.Stack; ...
- c# sharepoint client object model 客户端如何创建中英文站点
c# sharepoint client object model 客户端如何创建中英文站点 ClientContext ClientValidate = tools.GetContext(Onlin ...
- ASP.NET SignalR 系列(一)之SignalR介绍
一.SignalR介绍 ASP.NET SignalR 是一个面向 ASP.NET 开发人员的库,可简化将实时 web 功能添加到应用程序的过程. 实时 web 功能是让服务器代码将内容推送到连接的客 ...
- k8s--scope.yaml
- SpringBoot1.x升级SpringBoot2.x踩坑之文件上传大小限制
SpringBoot1.x升级SpringBoot2.x踩坑之文件上传大小限制 前言 LZ最近升级SpringBoo框架到2.1.6,踩了一些坑,这里介绍的是文件上传大小限制. 升级前 #文件上传配置 ...
- 手写MQ框架(二)-服务端实现
一.起航 书接上文->手写MQ框架(一)-准备启程 本着从无到有,从有到优的原则,所以计划先通过web实现功能,然后再优化改写为socket的形式. 1.关于技术选型 web框架使用了之前写的g ...
- css,对包含有子元素的元素进行flex后,会影响原有的布局。如何后续处理
对包含有子元素的元素进行flex后,会影响原有的布局. 例如设置两个div,第一个div包含一个img(图片),第二个div包含多个p元素(对前面的img的说明).如下图 1:当对着两个两个div进行 ...
fmt.Println()