分享
  1. 首页
  2. 文章

关于golang struct interface的理解使用

rfyiamcool · · 1735 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

前端时间说了不少golang常用库包的使用,貌似没有详细说struct interface的概念。在说interface之前,我们知道在Golang 中是没有类class 的概念,golang是通过 interface 类型接口实现的继承多态的效果。

一个 interface 类型定义了一个方法集做接口。 使用golang实现继承时,我们只要记得要给我们的interface类型实现一个method,就完成了对interface的使用。

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。

http://xiaorui.cc/?p=2938

我们首先要区分出goalng的方法和函数。他们之间虽然都是通过func定义的,但还是有区别的。

这是函数,很直接的函数。

Python
1
2
3
4
func go(){
fmt.Println('go to home')
}

这是struct结构体,后面的move()函数是car结构体的一个方法。 如果move的方法类型是g *car,那么g是指针。 初始化了car后,可以直接用car的对象调用move方法。

Python
1
2
3
4
5
6
7
8
9
typecarstruct{
name string
num int
}
func(gcar)move(){
fmt.Println("driver car ,xiaorui.cc ")
}

另外在golang里某个函数想调用其他函数有这么几个用法。 方法,基于方法的interface接口,直接传参传对象。

然后来说下interface的用法:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//使用type定义一个interface
typeXiaoruiinterface{
Play()
Start(msg string)
}
//定义a为空接口
varainterface{}
variint=5
s:="Hello world"
//a可以存储任意类型的数值
a=i
a=s

一个函数把interface{}作为参数,那么他可以接受任意类型的值作为参数,如果一个函数返回interface{},那么也就可以返回任意类型的值。是不是很有用啊!

这是一个golang interface的实例代码。

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#xiaorui.cc
package main
import"fmt"
typeSstruct{
iint
}
func(p*S)Get()int{
returnp.i
}
func(p*S)Put(vint){
p.i=v
}
typeIinterface{
Get()int
Put(int)
}
func f1(pI){
fmt.Println(p.Get())
p.Put(888)
}
funcf2(pinterface{}){
switcht:=p.(type){
case int:
fmt.Println("this is int number")
caseI:
fmt.Println("I:",t.Get())
default:
fmt.Println("unknow type")
}
}
//指针修改原数据
func dd(a*S){
a.Put(999)
fmt.Println(a.Get(),"in dd func")
}
//临时数据
func aa(aS){
a.Put(2222)
fmt.Println(a.Get(),"in aa func")
}
func main(){
varsS
s.Put(333)
fmt.Println(s.Get())
f1(&s)
fmt.Println(s.Get())
f2(&s)
dd(&s)
fmt.Println(s.Get())
aa(s)
fmt.Println(s.Get())
}

运行后的结果是:

Python
1
2
3
4
5
6
7
8
9
333
333
888
I:888
999indd func
999
2222inaa func
999

下面是我的自问自答,也是我学习golang中的疑问... 请忽视问题的质量.


第一个问题,为什么s可以直接调用Put函数

首先s是用S结构体创建的,S有Get() Put()两个方法。所以s可以执行Put()

第二个问题,f函数为什么也能Get()

因为S实现了I类型的接口,换句话说,S实现了I interface类型定义好的方法,那么I定义也就有了Get方法。

第三个问题, f2的interface{}空接口用途

interface{}空接口可以是任何类型,我们可以在逻辑用断言的方式区别他是什么类型,然后根据类型做相应的处理。对应到上面的代码, 我给你给他传任何值,f2因为是空间口都会接收进来。
后面的 t := p.(type)是断言,所谓的断言就是区分他的type类型。 如果你不想使用switch,可以用下面的笨方法。

Python
1
2
3
4
5
6
7
8
9
10
funcg(somethinginterface{}){
ift,ok:=something.(I);ok{
fmt.Println("I:",t.Get())
}elseift,ok:=something.(int);ok{
fmt.Println("int:",t)
}else{
fmt.Println("not found:",something)
}
}


空接口可代表任何类型,可做形参和返回类型

第四个问题,f1 f2 为什么要使用指针?

看代码中的类型,我被自己坑了好几次。
func (p *S) Get() int {
func (p *S) Put(v int) {

上面是interface的种种用法。下面是个google出来的一个goalng interface的例子。

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#xiaorui.cc
package main
import(
"fmt"
)
//定义了一个接口
typeIinterface{
Get()int
Put(int)
}
typeSstruct{iint}
func(p*S)Get()int{returnp.i}
func(p*S)Put(vint){p.i=v}
typeRstruct{iint}
func(p*R)Get()int{returnp.i}
func(p*R)Put(vint){p.i=v}
func f1(pI){
fmt.Println(p.Get())
p.Put(1)
}
//interface{}空接口,能接受任何类型。.(I)是类型断言.
funcf2(pinterface{}){
ift,ok:=p.(S);ok{
fmt.Println("S:",t)
}elseift,ok:=p.(I);ok{
fmt.Println("I:",t.Get())
}
}
funcf3(pinterface{}){
switcht:=p.(type){
caseS:
fmt.Println("S:",t.Get())
caseR:
fmt.Println("R:",t.Get())
caseI:
fmt.Println("I:",t.Get())
default:
fmt.Println("unknow type")
}
}
func main(){
s:=S{101}
f1(&s)
f2(&s)
r:=R{1111}
f3(&r)
}


最后啰嗦一下. 上面的结构S实现了I接口的两个方法,因此可以说是S实现了I接口。又因为S实现了I,因此可以f函数向其传递s,而且可以调动s的那两个方法。

对于golang interface我没有从更深的层面去讲述,为什么? 因为我也不懂太深... 以上对于interface讲述有不对的地方,欢迎来指点下。

要看清方法是否是指针.

Python
1
2
3
4
# command-line-arguments
./in.go:44:cannot uses(typeS)astypeIinargument to f1:
Sdoes notimplementI(Get method has pointer receiver)

有疑问加站长微信联系(非本文作者)

本文来自:峰云就她了

感谢作者:rfyiamcool

查看原文:关于golang struct interface的理解使用

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1735 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏