package main
import"fmt"//自定义类型type XX stringtype Person struct{
name string
sex bool
age int}type Student struct{//匿名字段
Person
id int
address string//同名函数
name string//基础匿名字段
XX
//指针类型
eat *string}funcmain(){//初始化
s := Student{Person{"LGL",true,20},001,"JX","Tom","XX",&"eat"}
fmt.Println(s)//输出 {{LGL true 20} 1 JX Tom}//成员操作
fmt.Println(s.name)//输出 Tom//同名函数 就近原则
s.name ="Test"
fmt.Println(s)//输出 {{LGL true 20} 1 JX Test}
s.Person.name ="XXX"
fmt.Println(s)//输出 {{XXX true 20} 1 JX Test}}
2.方法
要注意方法和函数是不一样的
面向对象和面向过程的方法区别
package main
import"fmt"//实现两数相加//1.面向过程funcAdd1(a, b int)int{return a + b
}//2.面向对象type MyNum int//tmp:接收者,接收者就是传递的一个参数func(tmp MyNum)Add2(other MyNum) MyNum {return tmp + other
}funcmain(){
fmt.Println(Add1(1,2))var a MyNum =2
fmt.Println(a.Add2(3))}
结构体类型添加方法
接收的类型不同,同名也没关系,类似重载
package main
import"fmt"type Student struct{
name string
sex bool
age int}func(tmp Student)Print(){
fmt.Println(tmp)}//通过成员函数 给成员赋值func(p *Student)Op(name string, sex bool, age int){
p.name = name
p.sex = sex
p.age = age
}funcmain(){
s := Student{"LGL",true,18}
s.Print()//输出 {LGL true 18}var p Student
(&p).Op("ZS",false,19)
p.Print()//输出 {ZS false 19}}
这里也要注意一下引用传递和值传递的方法,和之前一样
package main
import"fmt"type Student struct{
name string
sex bool
age int}func(temp Student)PrintInfo(){
fmt.Println(temp)}//值传递与引用传递//接收者为普通变量 非指针 值语义 一份拷贝func(temp Student)setInfoValues(n string, s bool, a int){
temp.name = n
temp.sex = s
temp.age = a
fmt.Println("setInfoValues = ", temp)//setInfoValues = {B false 21}}//接收者为指针变量 引用传递func(temp *Student)setInfoPointer(n string, s bool, a int){
temp.name = n
temp.sex = s
temp.age = a
fmt.Println("setInfoPointer = ", temp)//setInfoPointer = &{C true 22}}funcmain(){
s1 := Student{"A",true,20}
fmt.Println("1 = ", s1)//1 = {A true 20}
s1.setInfoValues("B",false,21)
fmt.Println("2 = ", s1)//2 = {A true 20}
s1.setInfoPointer("C",true,22)
fmt.Println("3 = ", s1)//3 = {C true 22}}
方法集
package main
import"fmt"type Student struct{
name string
sex bool
age int}func(temp Student)SetInfoValues(){
fmt.Println("SetInfoValues")}func(temp *Student)SetInfoPointer(){
fmt.Println("SetInfoPointer")}funcmain(){//结构体变量是一个指针变量,它能够调用哪些方法,这些方法就是一个集合,简称方法集
p :=&Student{"Tom",false,12}
p.SetInfoPointer()//内部做了转换,先把指针p 转成*p后再调用
p.SetInfoValues()}
方法继承
package main
import"fmt"type Person struct{
name string
sex bool
age int}//人类输出func(temp *Person)PrintInfo(){
fmt.Println(temp)}//学生 继承 人类type Student struct{
Person
id int
address string}funcmain(){
p := Student{Person{"A",true,20},001,"jx"}
p.PrintInfo()//&{A true 20}//方法也同样继承}
方法重写
package main
import"fmt"type Person struct{
name string
sex bool
age int}//人类输出func(temp *Person)PrintInfo(){
fmt.Println(temp)}//学生 继承 人类type Student struct{
Person
id int
address string}//学生输出func(temp *Student)PrintInfo(){
fmt.Println(temp)}funcmain(){
p := Student{Person{"A",true,20},001,"jx"}
p.PrintInfo()//&{{A true 20} 1 jx}
p.Person.PrintInfo()//&{A true 20}//就近原则输出}
方法值:给方法调用赋值一个变量 p := Person.Println()
方法表达式: 给方法名赋值一个变量 p:= Person.Println p(xxx)
3.接口
接口的命名通常会以er结尾
多态的表现
package main
import"fmt"type Personer interface{Eat()}type Student struct{
name string
id int}func(temp *Student)Eat(){
fmt.Println("Eat", temp)}type TT struct{
name string
id int}func(temp *TT)Eat(){
fmt.Println("TT", temp)}//多态funcWho(p Personer){
p.Eat()}funcmain(){//var p Personer
s :=&Student{"LGL",1}
t :=&TT{"TT",1}//p = s//p.Eat()//只要初始类型继承此接口就可以多态Who(s)//Eat &{LGL 1}Who(t)//TT &{TT 1}//创建一个切片
x :=make([]Personer,2)
x[0]= s
x[1]= t
for_, i :=range x {
fmt.Println("i:", i)}}
接的继承口
package main
import"fmt"type Iner1 interface{Eat()}type Iner2 interface{
Iner1
Sleep()}//定义一个学生type Student struct{
name string
id int}//实现吃的接口func(temp *Student)Eat(){
fmt.Println("Eat")}//实现睡觉的接口func(temp *Student)Sleep(){
fmt.Println("Sleep")}funcmain(){var i Iner2
s :=&Student{"LGL",0}
i = s
i.Eat()
i.Sleep()}
接口转换
package main
import"fmt"//子集type Iner1 interface{Eat()}//超集type Iner2 interface{
Iner1
Sleep()}//定义一个学生type Student struct{
name string
id int}//实现吃的接口func(temp *Student)Eat(){
fmt.Println("Eat")}//实现睡觉的接口func(temp *Student)Sleep(){
fmt.Println("Sleep")}funcmain(){//接口转换 超集 ——> 子集 反之不允许var i1 Iner1
var i2 Iner2
//OK
i1 = i2
//NO
i2 = i1
fmt.Println(i1)
fmt.Println(i2)}
空接口
funcmain(){//空接口为万能类型var i interface{}=1
fmt.Println(i)
i ="Hello World"
fmt.Println(i)}
类型查询
断言
package main
import"fmt"type Student struct{
name string
id int}funcmain(){
i :=make([]interface{},3)
i[0]=1
i[1]="H"
i[2]= Student{"lgl",123}//查询类型 类型断言for index, data :=range i {//第一个返回的是值 第二个是真假if value, ok := data.(int); ok ==true{
fmt.Println("index = ", index,"为int类型,值为:", value)//index = 0 为int类型,值为: 1}elseif value, ok := data.(string); ok ==true{
fmt.Println("index = ", index,"为string类型,值为:", value)//index = 1 为string类型,值为: H}elseif value, ok := data.(Student); ok ==true{
fmt.Println("index = ", index,"为Student类型,值为:", value)//index = 2 为Student类型,值为: {lgl 123}}}}
- switch
//查询类型 类型断言for index, data :=range i {switch value := data.(type){caseint:
fmt.Println("index = ", index,"为int类型,值为:", value)casestring:
fmt.Println("index = ", index,"为string类型,值为:", value)case Student:
fmt.Println("index = ", index,"为Student类型,值为:", value)}}
1.匿名组合package mainimport "fmt"//自定义类型type XX stringtype Person struct { name string sex bool age int}type Student struct { //匿名字段 Person id int address string //同名函数 name s...