- 匿名字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package main
import (
"fmt"
)
type person struct{
name string
age int
sex string
}
type Student struct{
person
id int
score int
}
func main(){
Student := Student{person{"张三", 100, "男"}, 1, 100}
fmt.Println(Student)
fmt.Println(Student.name) // 子结构体可以继承父结构体的字段
fmt.Println(Student.person.name)
}
继承中,子结构体和父结构体如果有同名字段,采用就近原则,会优先去当前结构体的,如果没有再去取父结构体的
1 | package main |
多继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package main
import "fmt"
type DemoA struct{
name string
id int
}
type DemoB struct{
age int
asex string
}
type DemoC struct{
DemoA
DemoB
score int
}
func main (){
var s DemoC = DemoC{DemoA{"name", 10}, DemoB{18, "man"}, 100}
fmt.Println(s)
}方法的定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package main
import "fmt"
type Int int
// 方法的对象必须是本地定义的
func (a Int) add (b Int, c Int) Int{
return a + b + c
}
func main (){
var s Int = 10
var b Int = 2
var c Int =1
s = s.add(b, c)
fmt.Println(s)
}方法实例
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
36package main
import "fmt"
type Stu struct {
name string
age int
sex string
}
func (s *Stu) init_info(name string, age int, sex string){
s.name = name
s.age = age
s.sex = sex
}
func (s Stu) printInfo(){
fmt.Println(s)
}
// 定义方法时,如果要修改所属对象的字段,需要将所属对象定义为指针类型,普通定义再函数退出后会被销毁,原因我也不清楚,有清楚的大佬,欢迎在评论区指正
func (s *Stu) editInfo(name string, age int, sex string){
s.name = name
s.age = age
s.sex = sex
}
func main(){
var s Stu
//s = new(Stu)
s.init_info("sss", 18, "man")
s.printInfo()
s.editInfo("xxx", 20, "women")
s.printInfo()
}方法的继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package main
import "fmt"
type Person struct{
id int
name string
age int
sex string
}
type student struct {
Person
score int
}
func (p *Person) sayHello(){
fmt.Println("我是",p.name)
}
func main (){
var s = student{Person{1,"sss", 28, "man"}, 100}
fmt.Println(s)
s.sayHello()
}
方法的重写:直接重写一个子对象的同名方法即可实现方法重写
接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package main
import "fmt"
type interfaceName interface{
sayHello()
}
type stu struct {
name string
}
func sayHi(s interfaceName){
s.sayHello()
}
func (s stu)sayHello(){
fmt.Println("I am ",s.name)
}
func main(){
var tmp interfaceName = stu{"storm"}
sayHi(tmp)
}我初看接口这个知识点的时候,很疑惑,用不用接口都得实现方法,接口到底有什么用?后来看了这篇关于go语言接口的文章豁然开朗,附文章链接:“Go语言关于Interface的理解与思考”
空接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17package main
import "fmt"
func main(){
// 空指针可以接受任意类型数据
var i interface {}
i = 10
fmt.Println(i)
i = "hello world"
fmt.Println(i)
// 空指针切片
var s []interface{}
s = append(s, 1, "s", [3]int{1,2,3}, true)
fmt.Println(s)
}懂python的同学很容易看出来,这个空指针可以实现python的list数据结构,即list里面可以存放任意类型的数据
类型断言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package main
import "fmt"
func main(){
type aType interface{}
var s aType
type stru struct{
name string
}
s = stru{"name"}
value, ok := s.(aType) // 断言,data, ok := varaible.(type) data 为值,ok为bool值,type为需要断言的类型
if ok{fmt.Println(value)}
}error接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package main
import (
"errors"
"fmt"
)
func divede(a int, b int)(valur int, err error){
if b == 0{
return 0, errors.New("除数不能为0")
}else {
return a/b, nil
}
}
func main (){
a := 2
b :=0
result, err := divede(a, b)
if err != nil{
fmt.Println(err)
}else{
fmt.Println(result)
}
}panic异常
1
panic("hello world2")
defer延迟调用
go 的 defer 语句是用来延迟执行函数的,而且延迟发生在调用函数 return 之后1
defer func(){}()
recover 接口
在别的语言一般都有异常捕获机制,比如python的try except finally,那么go语言中的异常捕获机制可以使用recover接口时间,‘recever’ 表示恢复的意思,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
26package main
import "fmt"
func divide(a int, b int)int{
if b == 0{
panic("除数不能为0")
}else{
return a/b
}
}
func main(){
a := 2
b := 0
defer func(){
err := recover()
if err != nil{
if err == "除数不能为0"{
fmt.Println(err)
}
}
}()
c := divide(a,b)
fmt.Println(c)
}文件创建和写入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package main
import (
"fmt"
"os"
)
func main(){
fp, err := os.Create("test.txt")
if err != nil{
fmt.Println(err)
}
fp.WriteString("哈哈")
defer fp.Close()
}