接口类型变量

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与接口:实现接口的条件的更多相关文章

  1. 常用的函数式接口Function接口和常用的函数式接口Function接口默认方法andThen

    常用的函数式接口Function接口 package com.yang.Test.FunctionStudy; import java.util.function.Function; /** * ja ...

  2. 常用的函数式接口_Prodicate接口_默认方法or&negate和常用的函数式接口_Predicate接口练习_集合信息筛选

    常用的函数式接口_Prodicate接口_默认方法or&negate OR package com.yang.Test.PredicateStudy; import java.util.fun ...

  3. Delphi 的接口机制——接口操作的编译器实现过程(1)

    学习COM编程技术也快有半个月了,这期间看了很多资料和别人的程序源码,也尝试了用delphi.C++.C#编写COM程序,个人感觉Delphi是最好上手的.C++的模版生成的代码太过复杂繁琐,大量使用 ...

  4. PHP - 接口 - 多接口

    /* * 使用多接口 */ //定义接口1 interface IPerosn_one{ public function eat(); } //定义接口2 interface IPerson_two{ ...

  5. java:接口特性 接口与抽象类/普通类的区别

    接口 书面定义: Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 在ja ...

  6. PHP九大接口视频教程( 支付宝,QQ,短信接口,微信接口开发, 支付宝即时到账接口开发三级分销全套)

    PHP九大接口视频教程(  支付宝,QQ,短信接口,微信接口开发, 支付宝即时到账接口开发三级分销全套) 需要的联系我:QQ: 1844912514 PHP九大接口视频教程(  支付宝,QQ,短信接口 ...

  7. java接口,接口的特性,接口实现多态,面向接口编程

    package cn.zy.cellphone; /**接口是一种引用数据类型.使用interface声明接口,形式 * 形式:public interface 接口名称{} * 接口不能拥有构造方法 ...

  8. java-类与类,类与接口,接口与接口的关系

    1.类与类: - 继承关系,只能单继承,可以多层继承. 2.类与接口: - 实现关系,可以单实现,也可以多实现. - 并且还可以在继承一个类的同时实现多个接口. - * 例:class Demo ex ...

  9. php给app写接口进行接口的加密

    <?php/**inc解析接口客户端接口传输规则:1.用cmd参数(base64)来动态调用不同的接口,接口地址统一为 http://a.lovexpp.com2.将要传过来的参数组成一个数组, ...

  10. 什么是封装? ----------------php中"public"类似的访问修饰符分别有什么作用?----什么是抽象?抽象的关键字以及用法----- 什么是接口?接口的关键字以及用法-------------

    什么是封装? ------------------------------------封装是php面向对象的其中一个特性,将多个可重复使用的函数封装到一个类里面.在使用时直接实例化该类的某一个方法,获 ...

随机推荐

  1. Python+Requests+Re(正则)爬取某糗事百科图片(数据分析一)

    1.博客目前在学习爬虫课程,使用正则表达式来爬取网页的图片信息 2.下面我们一起来回归下Python中的正则使用方式/方法 3.糗事百科图片爬取源码如下: import requestsimport ...

  2. Vue中Object和Array数据变化侦测原理

    在学完Vue.js框架,完成了一个SPA项目后,一直想抽时间找本讲解Vue.js内部实现原理的书来看看,经过多方打听之后,我最后选择了<深入浅出Vue.js>这本书.然而惭愧的是,这本书已 ...

  3. 在 Golang 中实现一个简单的Http中间件

    本文主要针对Golang的内置库 net/http 做了简单的扩展,通过添加中间件的形式实现了管道(Pipeline)模式,这样的好处是各模块之间是低耦合的,符合单一职责原则,可以很灵活的通过中间件的 ...

  4. Lambda 方法引用 构造器引用 数组引用

    一.方法引用 注意: 1.Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中的抽象方法的函数列表和返回值保持一致!2.若Lambda 参数列表中的第一个参数是实例方法的调用者,而第二个 ...

  5. Springboot+Mybatis+小程序

    思维导图: 项目效果图 一览界面: 新增界面:

  6. 开发工具IDE从入门到爱不释手(三)运行与调试

    一.启动项目 右键运行 菜单运行 run窗口运行 启动参数 -D可覆盖,application.properties中的配置 如: 自动编译 二.调试项目 断点调试 蓝色背景的行,就是当前程序停住的行 ...

  7. 一个完整的socket recv()案例,包括解决粘包、服务器主动推数据的问题

    前言: 本文是针对socket长连接(涉及到服务器主动推数据),每个包头的拼接算法和长度都不一样,具体的包头小伙伴们问自己公司的开发吧,本文只是提供思路.再啰嗦一句:recv到的包头中数字进行某种运算 ...

  8. Easyui设置easyui-textbox不可编辑

    转载自:https://blog.csdn.net/qq_23113521/article/details/78801689 在easyui里由于easyui-textbox被封装,通过一般的jque ...

  9. SSH远程端口转发实战详解

    问题 前段时间在外地没有在实验室,随身携带了一个笔记本电脑.但是笔记本性能不够,想用SSH远程连接实验室的电脑.问如何连接?现有以下设备 设备 IP 备注 系统 实验室电脑C1 192.168.0.2 ...

  10. Hadoop 3.1.1 - Yarn - 使用 CGroups

    在 Yarn 上使用 CGroups CGroups 是一种将任务及其子任务聚集和划分进一个垂直的分组的策略,并提供在此结构上的特别的操作.CGroups 是 Linux 内核功能,自内核版本 2.6 ...