接口类型变量

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. Mybatis order by 动态传参出现的一个小bug

    大家好,我是老三,一个平平无奇的CRUD仔. 今天,我正在愉快地CRUD,突然发现出现一个Bug,我们来看看是怎么回事吧! 问题由来 一个简单的需求,要求把和当前用户相关的数据置顶展示. 这里,我用了 ...

  2. vulnhub-DC:1靶机渗透记录

    准备工作 在vulnhub官网下载DC:1靶机https://www.vulnhub.com/entry/dc-1,292/ 导入到vmware 打开kali准备进行渗透(ip:192.168.200 ...

  3. 《手把手教你》系列技巧篇(十一)-java+ selenium自动化测试-元素定位大法之By tag name(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...

  4. 第1天 Mark Down 学习及DOS命令

    Markdown学习 标题 "#加空格"几个#就表示几级标题 字体 helloworld!一两个两个*号 helloworld!一边一个*号 helloworld! 一边三个号 h ...

  5. JBoss 4.x JBossMQ JMS 反序列化漏洞(CVE-2017-7504)

    检测漏洞 工具 下载地址:https://github.com/joaomatosf/JavaDeserH2HC javac -cp .:commons-collections-3.2.1.jar E ...

  6. RTB1靶机

    一.信息收集 信息收集 http://192.168.111.132/Hackademic_RTB1/?cat=1 http://192.168.111.132/Hackademic_RTB1/?ca ...

  7. 巧用map解决nginx的Location里if失效问题

    需求: Nginx根据参数来输出不同的header 我们想用Nginx来判断一些通用的参数, 根据参数情况在输出中不同的header, 或者cookie, 那么根据正常思路, 有如下配置: locat ...

  8. 浅谈vue响应式原理及发布订阅模式和观察者模式

    一.Vue响应式原理 首先要了解几个概念: 数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率. 双向绑定:数据改变,视图 ...

  9. oracle、postgres、mysql数据库的建库、创建用户、导人导出备份总结

    本文包含的内容:使用命令操作oracle.postgres.mysql的导入导出,登录到数据,创建用户 注:我在公司使用的是Center OS操作系统,所以oracle和postgres均是在Linu ...

  10. 如何远程调试自定义开发的Flume应用

    一.前言 Flume作为当下最流行的大数据采集组件之一.其本身拥有分布式/高可靠/高可用等优点,但相比较于Flink/Spark/Kafka等大数据组件,其对于本地调试的功能支持度并不高,如果我们没有 ...