目录
示例:发现输出哪里不同
package main
import "fmt"
//父结构体cart
type cart struct {
weight int
color string
}
//父结构体方法
func (c cart) run() {
fmt.Println("running")
}
//定义子结构体train
type train struct {
//继承cart
cart
wheel int
}
//子结构体方法
func (t train) String() string {
str := fmt.Sprintf("color:[%s],weight:[%d],wheel:[%d]", t.color, t.weight, t.wheel)
return str
}
func main() {
var train train
train.color = "绿色"
train.weight = 140000
train.wheel = 16
fmt.Println(train)
train.run()
fmt.Printf("%s\n", train)
}
[Running] go run "f:\goProject\src\dev_code\day20\example7\main\main.go"
color:[绿色],weight:[140000],wheel:[16] //并没有调用子结构体的方法,实际使用了方法,内部
//实际是使用了接口的功能,调用了子接口的方法
running
color:[绿色],weight:[140000],wheel:[16]
[Done] exited with code=0 in 0.563 seconds
1,接口定义
概念: Interface类型可以定义一组方法, 不需要实现,并且不能包含任何变量,称之为接口。
接口不需要显示的实现,只需要一个变量, 含有接类型中的所有方法,那么这个变量就实现了这个接口,如果一个变量含有了多个interface类型的方法,那么这个变量就实现了多个接口。
语法:
type example interface{ Method1(参数列表)返回值列表 Method2(参数列表)返回值列表 ... }
示例:空接口使用
package main
import "fmt"
//接口定义
type Test interface{}
func main() {
var t Test
fmt.Printf("t的类型:%T,值:%v\n", t, t)
var a interface{} //也是一种定义接口形式
var b int
a = b
fmt.Printf("a的类型:%T,值:%v\n", a, a)
}
[Running] go run "f:\goProject\src\dev_code\day20\example8\main\main.go"
t的类型:<nil>,值:<nil> //接口就是相当于空指针
a的类型:int,值:0 //把什么东西赋给空接口,空接口就成了什么
[Done] exited with code=0 in 0.573 seconds
示例:结构体使用接口打印信息
package main
import "fmt"
//定义结构体
type student struct {
name string
age int
score float32
}
//定义接口:功能的抽象表现,不需要实现
type Test interface {
print()
}
//接口的实现
func (s student) print() {
fmt.Printf("name:[%s]\n", s.name)
fmt.Printf("age:[%d]\n", s.age)
fmt.Printf("name:[%f]\n", s.score)
}
func main() {
//申明接口变量
var t Test
//结构体初始化
var stu student = student{
name: "zhangsan",
age: 20,
score: 100,
}
var stu1 student = student{
name: "lisi",
age: 25,
score: 20,
}
stu.print() //也可以输出只代表个体stu
//结构体赋值
t = stu
//接口功能
t.print()
//结构体赋值
t = stu1
//接口功能
t.print()
}
[Running] go run "f:\goProject\src\dev_code\day21\example1\main\main.go"
name:[zhangsan]
age:[20]
name:[100.000000]
name:[zhangsan]
age:[20]
name:[100.000000]
name:[lisi]
age:[25]
name:[20.000000]
[Done] exited with code=0 in 0.539 seconds
传指针
package main
import "fmt"
//定义结构体
type student struct {
name string
age int
score float32
}
//定义接口:功能的抽象表现,不需要实现
type Test interface {
print()
}
//接口的实现 传指针
func (s *student) print() {
fmt.Printf("name:[%s]\n", s.name)
fmt.Printf("age:[%d]\n", s.age)
fmt.Printf("name:[%f]\n", s.score)
}
func main() {
//申明接口变量
var t Test
//结构体初始化
var stu student = student{
name: "zhangsan",
age: 20,
score: 100,
}
var stu1 student = student{
name: "lisi",
age: 25,
score: 20,
}
stu.print() //也可以输出只代表个体
//结构体赋值
t = &stu
//接口功能
t.print()
//结构体赋值
t = &stu1
//接口功能
t.print()
}
[Running] go run "f:\goProject\src\dev_code\day21\example1\main\main.go"
name:[zhangsan]
age:[20]
name:[100.000000]
name:[zhangsan]
age:[20]
name:[100.000000]
name:[lisi]
age:[25]
name:[20.000000]
接口中多方法的实现
示例:
package main
import "fmt"
//定义结构体
type student struct {
name string
age int
score float32
}
//定义接口:功能的抽象表现,不需要实现
//接口中包含多个方法,如果要使用这个接口,这个接口中的所有方法都要使用
type Test interface {
print()
sleep()
}
//接口的实现 传指针
func (s *student) print() {
fmt.Printf("name:[%s]\n", s.name)
fmt.Printf("age:[%d]\n", s.age)
fmt.Printf("name:[%f]\n", s.score)
}
func (s student) sleep() {
fmt.Println("正在睡觉")
}
func main() {
//申明接口变量
var t Test
//结构体初始化
var stu student = student{
name: "zhangsan",
age: 20,
score: 100,
}
//结构体赋值
t = &stu
//接口功能
t.print()
t.sleep()
}
[Running] go run "f:\goProject\src\dev_code\day21\example2\main\main.go"
name:[zhangsan]
age:[20]
name:[100.000000]
正在睡觉
[Done] exited with code=0 in 0.557 seconds
接口功能可以不使用方法一定要有
package main
import "fmt"
//定义结构体
type student struct {
name string
age int
score float32
}
//定义接口:功能的抽象表现,不需要实现
//接口中包含多个方法,如果要使用这个接口,这个接口中的所有方法都要使用
type Test interface {
print()
sleep()
}
//接口的实现 传指针
func (s *student) print() {
fmt.Printf("name:[%s]\n", s.name)
fmt.Printf("age:[%d]\n", s.age)
fmt.Printf("name:[%f]\n", s.score)
}
func (s student) sleep() {
fmt.Println("正在睡觉")
}
func main() {
//申明接口变量
var t Test
//结构体初始化
var stu student = student{
name: "zhangsan",
age: 20,
score: 100,
}
//结构体赋值
t = &stu
//接口功能
t.print()
// t.sleep()
}
[Running] go run "f:\goProject\src\dev_code\day21\example2\main\main.go"
name:[zhangsan]
age:[20]
name:[100.000000]
[Done] exited with code=0 in 0.557 seconds
2,多态
示例:为不同数据类型的实体提供统一的接口。
package main
import "fmt"
//定义父结构体
type person struct {
name string
age int
}
//定义结构体学生
type student struct {
person //继承
score float32
}
//定义结构体老师
type teacher struct {
person //继承
class string
}
//定义接口:功能的抽象表现,不需要实现
//接口中包含多个方法,如果要使用这个接口,这个接口中的所有方法都要使用
type Test interface {
print()
sleep()
}
//学生接口的实现
func (s student) print() {
fmt.Printf("name:[%s]\n", s.name)
fmt.Printf("age:[%d]\n", s.age)
fmt.Printf("name:[%f]\n", s.score)
}
func (s student) sleep() {
fmt.Println("正在睡觉")
}
//教师接口实现
func (t teacher) print() {
fmt.Printf("name:[%s]\n", t.name)
fmt.Printf("age:[%d]\n", t.age)
fmt.Printf("name:[%s]\n", t.class)
}
func (t teacher) sleep() {
fmt.Println("正在睡觉")
}
func main() {
//申明接口变量
var t Test
//结构体初始化学生
var stu student
stu.name = "zhangsan"
stu.age = 20
stu.score = 100
//结构体初始化教师
var tea teacher
tea.name = "lisi"
tea.age = 50
tea.class = "一班"
//学生使用接口功能
t = stu
//接口功能
t.print()
t.sleep()
fmt.Println("---------------------")
//教师使用接口功能
t = tea
//接口功能
t.print()
t.sleep()
}
[Running] go run "f:\goProject\src\dev_code\day21\example3\main\main.go"
name:[zhangsan]
age:[20]
name:[100.000000]
正在睡觉
---------------------
name:[lisi]
age:[50]
name:[一班]
正在睡觉
[Done] exited with code=0 in 0.553 seconds
示例:
package main
import "fmt"
//电脑的usb接口有三个功能分别是存储,鼠标,风扇功能
type computer struct {
name string
}
type USB interface {
mouse()
cunchu()
fengshan()
}
func (c computer) mouse() {
fmt.Println("正在使用鼠标功能")
}
func (c computer) cunchu() {
fmt.Println("正在使用u盘存储功能")
}
func (c computer) fengshan() {
fmt.Println("正在使用风扇功能")
}
func main() {
var u USB
var com computer = computer{
name: "usb接口",
}
fmt.Println(com)
u = com
u.mouse()
u.cunchu()
u.fengshan()
}
[Running] go run "f:\goProject\src\dev_code\day21\example4\main\main.go"
{usb接口}
正在使用鼠标功能
正在使用u盘存储功能
正在使用风扇功能
多接口实现
package main
import "fmt"
//多接口实现
//接口1
type test interface {
print()
}
//接口2
type test1 interface {
sleep()
}
//结构体
type student struct {
name string
age int
score float32
}
//接口1方法实现
func (s student) print() {
fmt.Printf("name:[%s]\n", s.name)
}
//接口2的方法实现
func (s student) sleep() {
fmt.Println("正在睡觉")
}
func main() {
//接口1变量
var t test
//接口2变量
var t1 test1
//初始化结构体
var stu student = student{
name: "zhangsan",
age: 20,
score: 100,
}
//调用接口实现功能
t = stu
t.print()
t1 = stu
t1.sleep()
}
[Running] go run "f:\goProject\src\dev_code\day21\example5\main\main.go"
name:[zhangsan]
正在睡觉
[Done] exited with code=0 in 0.539 seconds
3,系统接口调用
示例:使用接口进行排序。 结构体切片插入
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
//声明结构体
type student struct {
name string
age int
score float32
}
//声明一个切片
type studentarray []student
//实现sort排序接口
func (sa studentarray) Len() int {
return len(sa) //返回长度
}
func (sa studentarray) Less(i, j int) bool {
return sa[i].name > sa[j].name //成立是true
}
func (sa studentarray) Swap(i, j int) {
sa[i], sa[j] = sa[j], sa[i] //交换数值
}
func main() {
rand.Seed(time.Now().Unix()) //时间种子随机函数
//student切片
var stus studentarray
//生成10个结构体放入切片中
for i := 0; i < 10; i++ {
var stu student = student{
name: fmt.Sprintf("stu%d", rand.Intn(100)),
age: rand.Intn(120), //随机数
score: rand.Float32() * 100,
}
//结构体元素存入切片中
stus = append(stus, stu)
}
//遍历
for _, v := range stus {
fmt.Println(v)
}
//排序
fmt.Println("--------------------------")
sort.Sort(stus)
//遍历
for _, v := range stus {
fmt.Println(v)
}
}
[Running] go run "f:\goProject\src\dev_code\day21\example6\main\main.go"
{stu41 39 24.372263}
{stu11 95 7.653611}
{stu49 60 62.645496}
{stu62 43 63.027138}
{stu36 36 89.42971}
{stu36 58 18.596565}
{stu12 63 39.70508}
{stu71 4 74.418434}
{stu62 45 42.58918}
{stu23 78 8.72018}
--------------------------
{stu71 4 74.418434}
{stu62 45 42.58918}
{stu62 43 63.027138}
{stu49 60 62.645496}
{stu41 39 24.372263}
{stu36 36 89.42971}
{stu36 58 18.596565}
{stu23 78 8.72018}
{stu12 63 39.70508}
{stu11 95 7.653611}
[Done] exited with code=0 in 0.54 seconds
4,接口嵌套
示例:文件读写测试
package main
import "fmt"
//接口嵌套
//定义reader接口
type Reader interface {
read()
}
//定义writer接口
type Writer interface {
writer()
}
//定义嵌套的读写接口
type Readerwriter interface {
Reader //直接调用子接口的名称
Writer //直接调用子接口的名称
}
//定义结构体
type File struct{}
//接口的实现 值类型传递一般使用指针传递
func (f *File) read() {
fmt.Println("正在使用读功能")
}
func (f *File) writer() {
fmt.Println("正在使用写功能")
}
//定义读写操作函数
func Test(rw Readerwriter) {
rw.read()
rw.writer()
}
func main() {
//初始化文件
var f File
Test(&f)
}
[Running] go run "f:\goProject\src\dev_code\day22\example7\main\main.go"
正在使用读功能
正在使用写功能
[Done] exited with code=0 in 0.766 seconds
5,类型断言
作用:因为接口是一般类型, 需要明确具体类型的时候就需要使用类型断言。
package main
import "fmt"
//类型断言
func main() {
var a interface{}
var b int
a = b
fmt.Printf("a的类型:%T,a的结构%v\n", a, a)
//类型断言赋值
c := a.(int)
fmt.Printf("c的类型:%T,c的结构%v\n", c, c)
//处理过程称为断言处理
}
[Running] go run "f:\goProject\src\dev_code\day22\example2\main\main.go"
a的类型:int,a的结构0
c的类型:int,c的结构0
[Done] exited with code=0 in 0.576 seconds
可以做判断
package main
import "fmt"
//类型断言
func main() {
var a interface{}
var b string
a = b
fmt.Printf("a的类型:%T,a的结构%v\n", a, a)
//类型断言赋值
c, err := a.(int)
if err == true {
fmt.Printf("c的类型:%T,c的结构%v\n", c, c)
} else {
fmt.Println("不属于int类型")
}
//处理过程称为断言处理
}
[Running] go run "f:\goProject\src\dev_code\day22\example2\main\main.go"
a的类型:string,a的结构
不属于int类型
[Done] exited with code=0 in 0.556 seconds
示例:断言判断
package main
import "fmt"
func Test(p interface{}) {
v, err := p.(int)
if err == false {
fmt.Println("type is not int")
return
}
v += 2
fmt.Println(v)
}
func main() {
Test(10)
Test("hello")
}
[Running] go run "f:\goProject\src\dev_code\day22\example2\main\main.go"
12
type is not int
[Done] exited with code=0 in 0.577 seconds
示例:多类型判断
package main
import "fmt"
//多数据类型判断处理 长度不固定,类型不固定知道类型可以用切片
func classfile(items ...interface{}) {
//遍历复杂集合
for i, v := range items {
//switch...type结合类型判断
switch v.(type) {
case bool:
fmt.Printf("第%d个数据类型是bool\n", i)
case int, int8, int16, int32, int64:
fmt.Printf("第%d个数据类型是int\n", i)
case float32, float64:
fmt.Printf("第%d个数据类型是float\n", i)
case string:
fmt.Printf("第%d个数据类型是string\n", i)
default:
fmt.Printf("第%d个数据类型是其他类型\n", i)
}
}
}
func main() {
classfile("zhangsan", 25, 93.52, true, nil)
}
[Running] go run "f:\goProject\src\dev_code\day22\example3\main\main.go"
第0个数据类型是string
第1个数据类型是int
第2个数据类型是float
第3个数据类型是bool
第4个数据类型是其他类型
[Done] exited with code=0 in 0.591 seconds
6,链表使用
示例:
package main
import "fmt"
//使用接口实现链表插入
//定义节点结构体
type Linknode struct {
data interface{}
next *Linknode
}
//链表结构体
type Link struct {
head *Linknode
tail *Linknode
}
//头部插入
func (k *Link) inserthead(data interface{}) {
var node *Linknode = &Linknode{
data: data,
next: nil,
}
if k.head == nil && k.tail == nil {
k.head = node
k.tail = node
return
}
//节点平移
node.next = k.head
k.head = node
}
//尾部插入
func (k *Link) inserttail(data interface{}) {
var node *Linknode = &Linknode{
data: data,
next: nil,
}
if k.head == nil && k.tail == nil {
k.head = node
k.tail = node
return
}
//节点平移
k.tail.next = node
k.tail = node
}
//遍历
func (p *Link) Req() {
lp := p.head
for lp != nil {
fmt.Println(*lp)
lp = lp.next
}
}
func main() {
var L Link
for i := 0; i < 10; i++ {
L.inserthead(i)
L.inserttail(i)
}
//遍历
L.Req()
}
[Running] go run "f:\goProject\src\dev_code\day22\example5\main\main.go"
{9 0xc0000961e0}
{8 0xc0000961b0}
{7 0xc000096180}
{6 0xc000096150}
{5 0xc000096120}
{4 0xc0000960f0}
{3 0xc0000960c0}
{2 0xc000096090}
{1 0xc000096060}
{0 0xc000096078}
{0 0xc0000960a8}
{1 0xc0000960d8}
{2 0xc000096108}
{3 0xc000096138}
{4 0xc000096168}
{5 0xc000096198}
{6 0xc0000961c8}
{7 0xc0000961f8}
{8 0xc000096228}
{9 <nil>}
[Done] exited with code=0 in 0.538 seconds