每次学习并整理一个Golang的知识点,每天进步一点点。今天学习下go中的一个知识点:接口🤔
日省吾身
- 判断下面代码能否正常执行?如果可以,写出输出结果?
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
|
package main
import "fmt"
// W 结构体W
type W struct {
n int
}
func (x W) showD() int {
result := x.n + 10
return result
}
func (x W) showB() int {
result := x.n + 20
return result
}
// D 接口D
type D interface {
showD() int
}
// B 接口B
type B interface {
showB() int
}
func main() {
w := W{3}
var dog D = w
var boy B = w
fmt.Println(dog.showD())
fmt.Println(boy.showB())
}
|
思考后看下方答案…
答疑解惑
参考答案:
1. 可以执行。程序输出结果为:13 23
知识点:接口
一种类型实现多个接口,结构体 W
分别实现了接口 D
、B
,所以接口变量 dog
、boy
调用各自的方法 ShowD()
和 ShowB()
,输出 13、23。
以上,你做对了吗?😊
其他相关答案或补充知识点,欢迎在评论区留言补充!
拓展阅读
在Go语言中,一个类只要实现了一个接口要求的所有方法,我们就说这个类实现了该接口;
例如:
1
2
3
4
5
6
7
8
9
|
type File struct {
// ...
}
func (f *File) Read(buf []byte) (n int, err error)
func (f *File) Write(buf []byte) (n int, err error)
func (f *File) Seek(off int64, whence int) (pos int64, err error)
func (f *File) Close() error
|
这里我们定义了一个File类,并实现有Read()
、Write()
、Seek()
、Close()
等方法。设想我们有如下接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
type IFile interface {
Read(buf []byte) (n int, err error)
Write(buf []byte) (n int, err error)
Seek(off int64, whence int) (pos int64, err error)
Close() error }
type IReader interface {
Read(buf []byte) (n int, err error)
}
type IWriter interface {
Write(buf []byte) (n int, err error)
}
type ICloser interface {
Close() error
}
|
尽管File类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是File类实现了这些接口,可以进行赋值:
1
2
3
4
|
var file1 IFile = new(File)
var file2 IReader = new(File)
var file3 IWriter = new(File)
var file4 ICloser = new(File)
|
Go语言的非侵入式接口,看似只是做了很小的文法调整,实则影响深远。
- 其一,Go语言的标准库,再也不需要绘制类库的继承树图。你一定见过不少C++、Java、C# 类库的继承树图。这里给个Java继承树图: http://docs.oracle.com/javase/1.4.2/docs/api/overview-tree.html ;在Go中,类的继承树并无意义,你只需要知道这个类实现了哪些方法,每个方法是啥含义就足够了;
- 其二,实现类的时候,只需要关心自己应该提供哪些方法,不用再纠结接口需要拆得多细才合理。接口由使用方按需定义,而不用事前规划。
- 其三,不用为了实现一个接口而导入一个包,因为多引用一个外部的包,就意味着更多的耦合。接口由使用方按自身需求来定义,使用方无需关心是否有其他模块定义过类似的接口;
下期提问
1.下面代码中 A B 两处应该怎么修改才能顺利编译?
1
2
3
4
5
6
7
|
func main() {
var m map[string]int //A
m["a"] = 1
if v := m["b"]; v != nil { //B
fmt.Println(v)
}
}
|
2.写出下面代码片段的输出结果?
1
2
3
4
5
6
7
8
9
|
func main() {
s := [3]string{"a", "b", "c"}
s1 := s[:0]
s2 := s[:2]
s3 := s[1:2:cap(s)]
fmt.Println("s1:", len(s1), cap(s1))
fmt.Println("s2:", len(s2), cap(s2))
fmt.Println("s3:", len(s3), cap(s3))
}
|
答案及解析将在下期文章中给出,欢迎大家在评论区写出你的答案;独乐乐不如众乐乐,欢迎交流学习,互相进步。
欢迎转发和评论。更多优质原创文章,欢迎关注微信公众号“IYue爱月”或扫描下方二维码:
文章作者
xujpxm
上次更新
2020-10-12
许可协议
CC BY-NC-ND 4.0 非商业转载请注明出处(作者,原文链接),商业转载请联系作者授权,谢谢!