Go与接口:实现接口的条件

接口类型变量
Go是强类型语言,你不能将整数值赋值给浮点型变量。同样,也不能将没有实现接口的类型值赋值给接口类型变量。
// 1.定义变量是接口类型
var w io.Writer
// 2.将具体类型的值 赋值给这个变量, 要求这个具体类型实现了接口的所有方法
w = os.Stdout
w = new(bytes.Buffer)
w = time.Second // compile error: time.Duration 没有
var rwc io.ReadWriteCloser
rwc = os.Stdout
rwc = new(bytes.Buffer) // compile error: *bytes.Buffer lacks Close method
// 等式右边是接口类型
w = rwc
rwc = w // compile error: io.Writer lacks Close method
关于一个类型持有一个方法的规则
- T类型的值不持有*T指针的方法
- *T指针的值持有T类型的方法
所以可能会有*T指针值可以赋值为某接口类型变量而T类型的值不可以的情况
type myWriter struct {}
func (m *myWriter) Write(p []byte) (n int, err error) {
return
}
func main() {
var w io.Writer
w = myWriter{} // compile error: Cannot use 'myWriter{}' (type myWriter) as the type io.Writer Type does not implement 'io.Writer' as the 'Write' method has a pointer receiver
w = &myWriter{} // OK
}
接口类型封装和隐藏具体类型和它的值
接口变量会限制自己只能调用接口类型声明的方法,即便该变量被赋予的值原本有其他方法和成员变量,也无法调用
type myWriter struct {
scope string
}
func (m *myWriter) Write(p []byte) (n int, err error) {
return
}
func (m *myWriter) Func() {
return
}
func main() {
my := &myWriter{"cn"}
fmt.Println(my.scope) // OK
my.Func() // Ok
var w io.Writer
w = my
fmt.Println(w.scope) // compile error: w.scope undefined
w.Func() // compile error: w.Func undefined
}
这样的限定就像是对实参进行了一层安全包装,函数内部只知道实参是接口类型,并不知道其他的信息,也无法访问。
从之前的例子可以看到,大接口变量可以被赋值给小接口,被赋值后小接口也只能调用小接口的方法。
空接口存在的意义
空接口(interface{})即没有声明任何方法的接口。因为它什么都没有,所以它可以成为任何。
package main
import (
"bytes"
"fmt"
)
func emptyInterfaceIsAny() {
var any interface{}
any = true
fmt.Println(any)
any = 12.34
fmt.Println(any)
any = "hello"
fmt.Println(any)
any = map[string]int{"one": 1}
fmt.Println(any)
any = new(bytes.Buffer)
fmt.Println(any)
}
这很有用,fmt.Println方法就是通过定义参数是空接口类型,才能接收任务类型的实参传递
package main
import "fmt"
func printlnArgsIsEmptyInterface() {
fmt.Println(1, "hello", []string{"world"}) // 1 hello [world]
}
合理定义接口
接口是对一些有着相同属性实体抽象。那对一些相同属性定义是仁者见仁智者见智,评判抽象的好与坏的标准即:这个接口类型的使用者是否舒服、被使用的次数多不对。
文中展示的例子是对数字文化产品(如:音乐、电影和书籍)的抽象。
其中对音乐和电影抽象出的Streamer值得思考
type Streamer interface {
Stream() (io.ReadCloser, error)
RunningTime() time.Duration
Format() string
}
每个具体类型基于他们实现接口声明的所有方法隐式地实现了接口。在Go语言中我们可以在需要的时候定义一个新的抽象或者特定特点的组,而不需要修改具体类型的定义。
Go与接口:实现接口的条件的更多相关文章
- 常用的函数式接口Function接口和常用的函数式接口Function接口默认方法andThen
常用的函数式接口Function接口 package com.yang.Test.FunctionStudy; import java.util.function.Function; /** * ja ...
- 常用的函数式接口_Prodicate接口_默认方法or&negate和常用的函数式接口_Predicate接口练习_集合信息筛选
常用的函数式接口_Prodicate接口_默认方法or&negate OR package com.yang.Test.PredicateStudy; import java.util.fun ...
- Delphi 的接口机制——接口操作的编译器实现过程(1)
学习COM编程技术也快有半个月了,这期间看了很多资料和别人的程序源码,也尝试了用delphi.C++.C#编写COM程序,个人感觉Delphi是最好上手的.C++的模版生成的代码太过复杂繁琐,大量使用 ...
- PHP - 接口 - 多接口
/* * 使用多接口 */ //定义接口1 interface IPerosn_one{ public function eat(); } //定义接口2 interface IPerson_two{ ...
- java:接口特性 接口与抽象类/普通类的区别
接口 书面定义: Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 在ja ...
- PHP九大接口视频教程( 支付宝,QQ,短信接口,微信接口开发, 支付宝即时到账接口开发三级分销全套)
PHP九大接口视频教程( 支付宝,QQ,短信接口,微信接口开发, 支付宝即时到账接口开发三级分销全套) 需要的联系我:QQ: 1844912514 PHP九大接口视频教程( 支付宝,QQ,短信接口 ...
- java接口,接口的特性,接口实现多态,面向接口编程
package cn.zy.cellphone; /**接口是一种引用数据类型.使用interface声明接口,形式 * 形式:public interface 接口名称{} * 接口不能拥有构造方法 ...
- java-类与类,类与接口,接口与接口的关系
1.类与类: - 继承关系,只能单继承,可以多层继承. 2.类与接口: - 实现关系,可以单实现,也可以多实现. - 并且还可以在继承一个类的同时实现多个接口. - * 例:class Demo ex ...
- php给app写接口进行接口的加密
<?php/**inc解析接口客户端接口传输规则:1.用cmd参数(base64)来动态调用不同的接口,接口地址统一为 http://a.lovexpp.com2.将要传过来的参数组成一个数组, ...
- 什么是封装? ----------------php中"public"类似的访问修饰符分别有什么作用?----什么是抽象?抽象的关键字以及用法----- 什么是接口?接口的关键字以及用法-------------
什么是封装? ------------------------------------封装是php面向对象的其中一个特性,将多个可重复使用的函数封装到一个类里面.在使用时直接实例化该类的某一个方法,获 ...
随机推荐
- python + pytest基本使用方法(断言)
#pytest 的基本用法# 安装: pip install pytest#在当前目录下运行 : 输入 pytest# 1.断言#功能:用于计算a与b相加的和def add(a,b): return ...
- 查看JVM默认参数及微调JVM启动参数
目录 查看某个JVM进程堆内存信息 微调JVM启动参数 查看JVM的一些默认参数 参考廖雪峰老师的这篇 JVM调优的正确姿势: https://www.liaoxuefeng.com/article/ ...
- mybatis-3-核心配置文件
全局配置文件:mybatis-config.xml 1.引入外部配置文件(properties) date.properties外部配置文件 driver = com.mysql.cj.jdbc.Dr ...
- odoo里面的read_group写法
#计算数task_count = fields.Integer(compute='_compute_task_count', string="Task Count")def _co ...
- 网络编程之TCP客户端开发和TCP服务端开发
开发 TCP 客户端程序开发步骤 创建客户端套接字对象 和服务端套接字建立连接 发送数据 接收数据 关闭客户端套接字 import socket if __name__ == '__main__': ...
- Mol Cell丨吕志民团队揭示琥珀酰化介导的肿瘤细胞氧化应激调控新机制
蛋白质琥珀酰化修饰 (succinylation) ,作为赖氨酸酰化修饰家族的重要一员,于2011年由芝加哥大学赵英明教授团队在Nature Chemical Biology 发文被首次报道,并被评为 ...
- Redis是不是真的变慢了?
大家好,今天我们来学习一下如何确定Redis是不是真的变慢了. 我们在使用redis时一定会遇到变慢的时候,那我们如何来判断Redis是否真的变慢了呢, 一个最直接的方法就是查看Redis的响应延迟, ...
- Flutter 中的动画
Flutter 中动画的创建有很多种, 需要根据具体的需求选择不同的动画.如果只是简单的布局等的动画直接使用最简单的隐式动画就可以了,因为隐式动画是由框架控制的,所以仅仅只需要更改变需要变化属性就可以 ...
- 《MySQL实战45讲》(8-15)笔记
MySQL实战45讲 目录 MySQL实战45讲 第八节: 事务到底是隔离的还是不隔离的? 在MySQL里,有两个"视图"的概念: "快照"在MVCC里是怎么工 ...
- shell——sed编辑器
目录 一.sed编辑器 1.1.sed编辑器工作流程 读取: 执行: 显示: 1.2.格式 1.3.常用选项 1.4.常用操作 1.5.替换 一.sed编辑器 sed是一种流编辑器,流编辑器会在编辑器 ...