GO语言
01GO基础-001GO语言简介
01GO基础-002语言环境安装
01GO基础-003Go 语言结构
01GO基础-004Go 语言基础语法1
01GO基础-004Go 语言基础语法2
01GO基础-004Go 语言基础语法3
01GO基础-005Go 语言数据类型
01GO基础-006Go 语言变量
01GO基础-007Go 语言常量
01GO基础-008Go 语言运算符
01GO基础-009条件语句
01GO基础-010循环语句
01GO基础-011函数
01GO基础-012变量作用域
01GO基础-013数组
01GO基础-014指针
01GO基础-015结构体
01GO基础-016切片
01GO基础-017范围(Range)
01GO基础-018Map
01GO基础-019递归函数
01GO基础-020类型转换
01GO基础-021接口
01GO基础-022异常处理
01GO基础-023并发
01GO基础-024strings
01GO基础-025可变参数
01GO基础-026接口2
01GO基础-027异常处理2
01GO基础-028sync包详解
01GO基础-029Context
02GO进阶001包
02GO进阶002init()函数
02GO进阶003包的注意点
02GO进阶003使用go module导入本地包
02GO进阶004 time包
02GO进阶005 file操作
02GO进阶006 io操作
02GO进阶007 os包(文件 I/O、文件属性、目录与链接、创建和移除链接)
02GO进阶008复制文件
02GO进阶009断点续传
02GO进阶010 bufio包
02GO进阶011ioutil包
02GO进阶012遍历文件夹
02GO进阶013并发编程介绍
02GO进阶014Goroutine协程
02GO进阶015 GPM
02GO进阶016 runtime包
02GO进阶017 Channel
02GO进阶018 Goroutine池
02GO进阶019 定时器
02GO进阶020 select
02GO进阶021并发安全和锁
02GO进阶022sync
02GO进阶023原子操作
02GO进阶024 GMP原理与调度
02GO进阶025爬虫小案例
02GO进阶026 面向对象-匿名字段
02GO进阶026 面向对象-接口
02GO进阶027网络编程-互联网协议介绍
02GO进阶027网络编程-socket
02GO进阶027网络编程-http编程
02GO进阶027网络编程-websocket编程
02GO进阶028数据操作-MYSQL
02GO进阶028数据操作-REDIS
02GO进阶028数据操作-RTCD
02GO进阶028数据操作-ZOOKEEPER
02GO进阶028数据操作-KAFKA
02GO进阶028数据操作-RabbitMQ
02GO进阶028数据操作-ElasticSearch
02GO进阶028数据操作-NSQ
02GO进阶028数据操作-memcached
02GO进阶028数据操作-GORM
02GO进阶029beego框架-安装
02GO进阶029beego框架-快速入门
02GO进阶029beego框架-MVC架构介绍-controller设计-参数配置
02GO进阶029beego框架-MVC架构介绍-controller设计-路由设置
02GO进阶029beego框架-MVC架构介绍-controller设计-控制器函数
02GO进阶029beego框架-MVC架构介绍-controller设计-XSRF过滤
02GO进阶029beego框架-MVC架构介绍-controller设计-请求数据处理
02GO进阶029beego框架-MVC架构介绍-controller设计-Session控制
02GO进阶029beego框架-MVC架构介绍-controller设计-过滤器
02GO进阶029beego框架-MVC架构介绍-controller设计-Flash数据
02GO进阶029beego框架-MVC架构介绍-controller设计-URL构建
02GO进阶029beego框架-MVC架构介绍-controller设计-多种格式数据输出
02GO进阶029beego框架-MVC架构介绍-controller设计-表单数据验证
02GO进阶029beego框架-MVC架构介绍-controller设计-错误处理
02GO进阶029beego框架-MVC架构介绍-controller设计-日志处理
02GO进阶029beego框架-MVC架构介绍-model设计-概述
02GO进阶029beego框架-MVC架构介绍-model设计-CRUD操作
02GO进阶029beego框架-MVC架构介绍-model设计-高级查询
02GO进阶029beego框架-MVC架构介绍-model设计-原生SQL查询
02GO进阶029beego框架-MVC架构介绍-model设计-构造查询
02GO进阶029beego框架-MVC架构介绍-model设计-事务处理
02GO进阶029beego框架-MVC架构介绍-model设计-模型定义
02GO进阶029beego框架-MVC架构介绍-model设计-命令模式
02GO进阶029beego框架-MVC架构介绍-model设计-测试用例
02GO进阶029beego框架-MVC架构介绍-view设计-beego 模板语法指南
02GO进阶029beego框架-MVC架构介绍-view设计-模板处理
02GO进阶029beego框架-MVC架构介绍-view设计-其他
本文档使用 MrDoc 发布
-
+
首页
01GO基础-021接口
## 接口 接口(interface)是 Go 语言中的一种类型,用于定义行为的集合,它通过描述类型必须实现的方法,规定了类型的行为契约。 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。 Go 的接口设计简单却功能强大,是实现多态和解耦的重要工具。 接口可以让我们将不同的类型绑定到一组公共的方法上,从而实现多态和灵活的设计。 ## 接口的特点 隐式实现: 1) Go 中没有关键字显式声明某个类型实现了某个接口。 2) 只要一个类型实现了接口要求的所有方法,该类型就自动被认为实现了该接口。 接口类型变量: 1) 接口变量可以存储实现该接口的任意值。 2)接口变量实际上包含了两个部分: 2.1) 动态类型:存储实际的值类型。 2.2) 动态值:存储具体的值。 零值接口: 1) 接口的零值是 nil。 2) 一个未初始化的接口变量其值为 nil,且不包含任何动态类型或值。 空接口: 定义为 interface{},可以表示任何类型。 接口的常见用法 多态:不同类型实现同一接口,实现多态行为。 解耦:通过接口定义依赖关系,降低模块之间的耦合。 泛化:使用空接口 interface{} 表示任意类型。 ## 接口定义和实现 接口定义使用关键字 interface,其中包含方法声明。 ```go /* 定义接口 */ type interface_name interface { method_name1 [return_type] method_name2 [return_type] method_name3 [return_type] ... method_namen [return_type] } /* 定义结构体 */ type struct_name struct { /* variables */ } /* 实现接口方法 */ func (struct_name_variable struct_name) method_name1() [return_type] { /* 方法实现 */ } ... func (struct_name_variable struct_name) method_namen() [return_type] { /* 方法实现*/ } ``` 定义一个简单接口: ```go type Shape interface { Area() float64 Perimeter() float64 } ``` Shape 是一个接口,定义了两个方法:Area 和 Perimeter。 任意类型只要实现了这两个方法,就被认为实现了 Shape 接口。 实现接口: 类型通过实现接口要求的所有方法来实现接口。 实例 ```go package main import ( "fmt" "math" ) // 定义接口 type Shape interface { Area() float64 Perimeter() float64 } // 定义一个结构体 type Circle struct { Radius float64 } // Circle 实现 Shape 接口 func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius } func (c Circle) Perimeter() float64 { return 2 * math.Pi * c.Radius } func main() { c := Circle{Radius: 5} var s Shape = c // 接口变量可以存储实现了接口的类型 fmt.Println("Area:", s.Area()) fmt.Println("Perimeter:", s.Perimeter()) } ``` 执行以上代码,输出结果为: Area: 78.53981633974483 Perimeter: 31.41592653589793 ## 空接口 空接口 interface{} 是 Go 的特殊接口,表示所有类型的超集。 任意类型都实现了空接口。 常用于需要存储任意类型数据的场景,如泛型容器、通用参数等。 实例 ```go package main import "fmt" func printValue(val interface{}) { fmt.Printf("Value: %v, Type: %T\n", val, val) } func main() { printValue(42) // int printValue("hello") // string printValue(3.14) // float64 printValue([]int{1, 2}) // slice } ``` 执行以上代码,输出结果为: Value: 42, Type: int Value: hello, Type: string Value: 3.14, Type: float64 Value: [1 2], Type: []int ## 类型断言 类型断言用于从接口类型中提取其底层值。 基本语法: `value := iface.(Type)` iface 是接口变量。 Type 是要断言的具体类型。 如果类型不匹配,会触发 panic。 实例 ```go package main import "fmt" func main() { var i interface{} = "hello" str := i.(string) // 类型断言 fmt.Println(str) // 输出:hello } ``` ## 带检查的类型断言 为了避免 panic,可以使用带检查的类型断言: `value, ok := iface.(Type)` ok 是一个布尔值,表示断言是否成功。 如果断言失败,value 为零值,ok 为 false。 实例 ```go package main import "fmt" func main() { var i interface{} = 42 if str, ok := i.(string); ok { fmt.Println("String:", str) } else { fmt.Println("Not a string") } } ``` 执行以上代码,输出结果为: Not a string ## 类型选择(type switch) type switch 是 Go 中的语法结构,用于根据接口变量的具体类型执行不同的逻辑。 实例 ```go package main import "fmt" func printType(val interface{}) { switch v := val.(type) { case int: fmt.Println("Integer:", v) case string: fmt.Println("String:", v) case float64: fmt.Println("Float:", v) default: fmt.Println("Unknown type") } } func main() { printType(42) printType("hello") printType(3.14) printType([]int{1, 2, 3}) } ``` 执行以上代码,输出结果为: Integer: 42 String: hello Float: 3.14 Unknown type ## 接口组合 接口可以通过嵌套组合,实现更复杂的行为描述。 实例 ```go package main import "fmt" type Reader interface { Read() string } type Writer interface { Write(data string) } type ReadWriter interface { Reader Writer } type File struct{} func (f File) Read() string { return "Reading data" } func (f File) Write(data string) { fmt.Println("Writing data:", data) } func main() { var rw ReadWriter = File{} fmt.Println(rw.Read()) rw.Write("Hello, Go!") } ``` ## 动态值和动态类型 接口变量实际上包含了两部分: 动态类型:接口变量存储的具体类型。 动态值:具体类型的值。 动态值和动态类型示例: ```go package main import "fmt" func main() { var i interface{} = 42 fmt.Printf("Dynamic type: %T, Dynamic value: %v\n", i, i) } ``` 执行以上代码,输出结果为: Dynamic type: int, Dynamic value: 42 ## 接口的零值 接口的零值是 nil。 当接口变量的动态类型和动态值都为 nil 时,接口变量为 nil。 接口零值示例: ```go package main import "fmt" func main() { var i interface{} fmt.Println(i == nil) // 输出:true } ``` 练习实例 以下两个实例演示了接口的使用: 实例 1 ```go package main import ( "fmt" ) type Phone interface { call() } type NokiaPhone struct { } func (nokiaPhone NokiaPhone) call() { fmt.Println("I am Nokia, I can call you!") } type IPhone struct { } func (iPhone IPhone) call() { fmt.Println("I am iPhone, I can call you!") } func main() { var phone Phone phone = new(NokiaPhone) phone.call() phone = new(IPhone) phone.call() } ``` 在上面的例子中,我们定义了一个接口 Phone,接口里面有一个方法 call()。然后我们在 main 函数里面定义了一个 Phone 类型变量,并分别为之赋值为 NokiaPhone 和 IPhone。然后调用 call() 方法,输出结果如下: I am Nokia, I can call you! I am iPhone, I can call you! 第二个接口实例: 实例 ```go package main import "fmt" type Shape interface { area() float64 } type Rectangle struct { width float64 height float64 } func (r Rectangle) area() float64 { return r.width * r.height } type Circle struct { radius float64 } func (c Circle) area() float64 { return 3.14 * c.radius * c.radius } func main() { var s Shape s = Rectangle{width: 10, height: 5} fmt.Printf("矩形面积: %f\n", s.area()) s = Circle{radius: 3} fmt.Printf("圆形面积: %f\n", s.area()) } ``` 以上实例中,我们定义了一个 Shape 接口,它定义了一个方法 area(),该方法返回一个 float64 类型的面积值。然后,我们定义了两个结构体 Rectangle 和 Circle,它们分别实现了 Shape 接口的 area() 方法。在 main() 函数中,我们首先定义了一个 Shape 类型的变量 s,然后分别将 Rectangle 和 Circle 类型的实例赋值给它,并通过 area() 方法计算它们的面积并打印出来,输出结果如下: 矩形面积: 50.000000 圆形面积: 28.260000 需要注意的是,接口类型变量可以存储任何实现了该接口的类型的值。在示例中,我们将 Rectangle 和 Circle 类型的实例都赋值给了 Shape 类型的变量 s,并通过 area() 方法调用它们的面积计算方法。
admin
2024年12月20日 14:20
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码