Go -- 接口赋值
在go语言中,接口赋值分为2中情况:
1、将对象实例赋值给接口;
2、将一个接口赋值给另一个接口。
1、将对象实例赋值给接口:
要求对象实现了接口的所有方法。
2、将接口赋值给另一个接口:
假设接口A中定义的所有方法,都在接口B中有定义,那么B接口的实例可以赋值给A的对象。反之不成立,除非A和B定义的方法完全一样(顺序不要求),这时A和B等价,可以相互赋值。
3、类实例化时指针或者实例区别:
实例化类的时候,一般有2个方法:
(1) 用new(structName):这个方法得到的是*structName类型,即类的指针类型;
(2) 用structName{init para}:这个方法得到的是structName类型,即类的实例类型,不是指针。
注意:
类在实现接口的时候,要注意定义的时候,一般用类的指针传入,就可以了。因为如果用类的结构体的话,可能会导致“类没有实现接口中某个方法”的错误。详细举例:
package main
import "fmt"
type tmpInterface interface{
tmpFunc()
tmpFuncPtr()
}
type tmpStruct struct{
}
func(t tmpStruct)tmpFunc(){
fmt.Println("functmpFunc")
}
func(t *tmpStruct)tmpFuncPtr(){
fmt.Println("functmpFuncPtr")
}
funcmain(){
/*这里如果用new,则得到的是tmpStruct的指针,tmpInterface的2个方法都可用*/
var t_t tmpInterface=new(tmpStruct)
t_t.tmpFunc()
t_t.tmpFuncPtr()
/*这里如果用tmpStruct{},则得到的是tmpStruct的实例,tmpInterface的2个方法都可用*/
/*
var t_ptr tmpInterface=tmpStruct{}
t_ptr.tmpFunc()
t_ptr.tmpFuncPtr()
*/
}
上面的main()函数中,如果用tmpStruct{}初始化(可以理解为构造函数,没有入参),得到的是 tmpStruct的类型,会编译出错:
cannot use tmpStruct literal(type tmpStruct) as type tmpInterface in assignment:tmpStruct does not implementtmpInterface(tmpFuncPtr method has pointer receiver)
个人理解:
受之前对C++或者JAVA等面向对象语言的影响,我们会把定义类的代码(以及其方法)视为一体的,下面把代码再复制一份下来:
type tmpStruct struct{
}
func(t tmpStruct)tmpFunc(){
fmt.Println("functmpFunc")
}
func(t*tmpStruct)tmpFuncPtr(){
fmt.Println("functmpFuncPtr")
}
如果把上面这些代码理解成C++中对类tmpStruct的定义,函数tmpFunc和tmpFuncPtr是类的2个成员函数,那么会难以理解为什么又会提示tmpStruct没有实现tmpFuncPtr这个方法的提示。
其实go语言中,interface和struct之间的关系和传统的面向对象中的是非常不一样的,接口和类之间耦合度非常低。同时,对其之间关系起到连接作用的“成员函数”,个人感觉和类以及接口的耦合度也是非常低的,倒不如直接把这些“成员函数”直接理解成普通的方法,只是go语言中允许这样的特殊语法形式定义:
关键字 传入的类/类指针 正常的函数定义
func (t tmpStruct) tmpFunc() {…}
func (t *tmpStruct) tmpFuncPtr(){…}
在用类的实例/实例指针初始化接口的对象时:
var t_t tmpInterface=new(tmpStruct)
由于new返回的是一个指针,所以这里相当于t_t是一个*tmpStruct类型的变量,所以在调用函数的时候,给函数传入的就是一个指针。
摘抄一句《Go语言编程》里面的话(3.5.3:接口赋值):
Go语言可以根据下面的函数:
func (a Integer) Less(b Integer) bool
自动生成一个新的Less()方法:
func (a *Integer) Less(b Integer) bool {…}
就是说,有了结构体类型作为入参的函数,go语言会自动创建一个相应的指针作为入参的函数,但是只有指针入参的函数,不会创建相应的结构体类型的函数。
如果这样定义:
var t_ptr tmpInterface=tmpStruct{}
tmpStruct{}的结果是tmpStruct类型,如果允许赋值给t_ptr成功的话,那么调用t_ptr.tmpFuncPtr时因为传入类型错误,所以这个角度看,go直接让编译不通过也是可以理解的。
总结:如果类的“成员函数”中有传入结构体指针类型的,则必须用结构体指针类型实例化接口的实例。
Go -- 接口赋值的更多相关文章
- 【Go语言】面向对象扩展——接口
简单地说 Interface是一组Method的组合,可以通过Interface来定义对象的一组行为.如果某个对象实现了某个接口的所有方法,就表示它实现了该借口,无需显式地在该类型上添加接口说明. I ...
- 深入学习golang(5)—接口
接口 概述 如果说goroutine和channel是Go并发的两大基石,那么接口是Go语言编程中数据类型的关键.在Go语言的实际编程中,几乎所有的数据结构都围绕接口展开,接口是Go语言中所有数据结构 ...
- TypeScript学习指南第二章--接口(Interface)
接口(Interface) TypeScript的核心机制之一在于它的类型检查系统(type-checker)只关注一个变量的"模型(shape)" 稍后我们去了解这个所谓的形状是 ...
- Delphi 的接口机制——接口操作的编译器实现过程(2)
接口对象的内存空间 假设我们定义了如下两个接口 IIntfA 和 IIntfB,其中 ProcA 和 ProcB 将实现为静态方法,而 VirtA 和 VirtB 将以虚方法实现: IIntfA = ...
- Delphi 的接口机制——接口操作的编译器实现过程(1)
学习COM编程技术也快有半个月了,这期间看了很多资料和别人的程序源码,也尝试了用delphi.C++.C#编写COM程序,个人感觉Delphi是最好上手的.C++的模版生成的代码太过复杂繁琐,大量使用 ...
- Java基础学习(四)-- 接口、集合框架、Collection、泛型详解
接口 一.接口的基本概念 关键字为:Interface,在JAVA编程语言中是一个抽象类型,是抽象方法的集合.也是使用.java文件编写. 二.接口声明 命名规范:与类名的命名规范相同,通常情况下 ...
- Go第七篇之规范的接口
接口本身是调用方和实现方均需要遵守的一种协议,大家按照统一的方法命名参数类型和数量来协调逻辑处理的过程. Go 语言中使用组合实现对象特性的描述.对象的内部使用结构体内嵌组合对象应该具有的特性,对外通 ...
- [golang note] 接口使用
侵入式接口 √ 在其他一些编程语言中,接口主要是作为不同组件之间的契约存在,即规定双方交互的规约. √ 对契约的实现是强制的,即必须确保用户的确实现了该接口,而实现一个接口,需要从该接口继承. √ 如 ...
- Go语言 6 结构体、方法和接口
文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 结构体(struct)是由一系列具有相同类型或不同类 ...
随机推荐
- linux学习-用户的特殊 shell 与 PAM 模块
特殊的 shell, /sbin/nologin 『无法登入』指的是:『这个使用者无法使用 bash 或其他 shell 来登入系统』而已, 并不是说这个账号就无法使用其他的系统资源! 让某个具有 / ...
- CodeForces 543D 树形DP Road Improvement
题意: 有一颗树,每条边是好边或者是坏边,对于一个节点为x,如果任意一个点到x的路径上的坏边不超过1条,那么这样的方案是合法的,求所有合法的方案数. 对于n个所有可能的x,输出n个答案. 分析: 题解 ...
- day03 set集合,文件操作,字符编码以及函数式编程
嗯哼,第三天了 我们来get 下新技能,集合,个人认为集合就是用来list 比较的,就是把list 转换为set 然后做一些列表的比较啊求差值啊什么的. 先看怎么生成集合: list_s = [1,3 ...
- java基础语法中容易出错的细节
1 java中的数字默认类型为int **容易出现类型转换错误 long 定义的数字后面必须有 “l” “L” float 定义的数字后面必须有 “f” “F” java中比int表述范围大的数,不会 ...
- web安全测试---跨站点脚本测试
1.1 跨站脚本测试 1.1.1 GET方式跨站脚本测试 编号 SEC_Web_XSS_01 测试用例名称 GET方式跨站脚本测试 测试目的 由于跨站脚本会导致会话被劫持.敏感 ...
- Python学习-day10 进程
学习完线程,学习进程 进程和线程的语法有很多一样的地方,不过在操作系统中的差别确实很大. 模块是threading 和 multiprocessing 多进程multiprocessing multi ...
- [PDOException] SQLSTATE[HY000] [2002] No such file or directory
编译安装PHP7之后,在安装mysql之后,用pdo操作数据库的时候,出现了此错误[PDOException] SQLSTATE[HY000] [2002] No such file or direc ...
- POJ——3070Fibonacci(矩阵快速幂)
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12329 Accepted: 8748 Descri ...
- HDU——1418抱歉(平面欧拉公式)
抱歉 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- [SCOI2011]糖果 (差分约束)
题目链接 Solution 差分约束乱搞就好了. 需要注意的地方: 对于大于等于的直接联等于,应为等于,因为对于我满足条件而言,等于总是最好的. 对于等于的,注意要建双向边. 然后要开 \(long~ ...