golang 函数数组、接口数组和管道数组
1. 函数数组(Function Arrays)
定义:数组的元素是函数,所有函数必须具有相同的参数类型和返回类型。
用途:用于存储多个具有相同签名的函数,实现动态选择或策略模式。
示例代码
package main
import "fmt"
// 定义两个函数,具有相同的签名
func add(x, y int) int { return x + y }
func multiply(x, y int) int { return x * y }
func main() {
// 函数数组:存储两个函数
funcArray := [2]func(int, int) int{add, multiply}
// 调用数组中的函数
fmt.Println(funcArray[0](3, 4)) // 输出:7(3+4)
fmt.Println(funcArray[1](3, 4)) // 输出:12(3×4)
// 动态选择函数
operations := [...]func(int, int) int{add, multiply}
for _, op := range operations {
fmt.Println(op(5, 6)) // 输出:11(5+6)、30(5×6)
}
}
关键点
- 函数类型一致性:数组中的所有函数必须具有相同的参数和返回类型。
- 动态调用:通过索引或循环遍历调用不同函数,适用于策略模式或插件系统。
- 适用场景:数学运算、事件处理、动态策略选择等。
2. 接口数组(Interface Arrays)
定义:数组的元素是 interface{} 类型,可存储任意类型值。
用途:实现动态类型存储,支持类型断言和多态行为。
示例代码
package main
import "fmt"
func main() {
// 接口数组:存储不同类型的值
interfaceArray := [3]interface{}{
42, // int
"Hello, Go!", // string
struct{ Name string }{Name: "Alice"}, // 匿名结构体
}
// 遍历并处理元素
for _, value := range interfaceArray {
switch v := value.(type) {
case int:
fmt.Printf("Integer: %d\n", v)
case string:
fmt.Printf("String: %s\n", v)
case struct{ Name string }:
fmt.Printf("Struct: Name = %s\n", v.Name)
default:
fmt.Println("Unknown type")
}
}
}
关键点
-
动态类型存储:数组元素可以是任意类型(如
int,string, 结构体等)。 -
类型断言:通过
switch或value.(type)进行类型检查和转换。 -
适用场景:需要存储异构数据的场景(如配置项、插件系统)。
3. 管道数组(Channel Arrays)
定义:数组的元素是通道(chan T),用于管理多个通道的通信。
用途:协调多个 goroutine 之间的并发通信。
示例代码
package main
import "fmt"
func main() {
// 声明并初始化通道数组
chs := [2]chan int{
make(chan int), // 通道0
make(chan int), // 通道1
}
// 启动goroutine向通道发送数据
go func() {
chs[0] <- 100
chs[1] <- 200
}()
// 接收数据
fmt.Println(<-chs[0]) // 输出:100
fmt.Println(<-chs[1]) // 输出:200
// 关闭通道(避免资源泄漏)
close(chs[0])
close(chs[1])
}
关键点
- 通道初始化:必须用
make(chan T)显式创建通道,否则通道值为nil。 - 并发操作:通过
goroutine发送/接收数据,实现多线程通信。 - 适用场景:管理多个生产者/消费者通道、分布式任务队列等。
总结对比表
| 类型 | 元素类型 | 核心特性 | 典型用途 |
|---|---|---|---|
| 函数数组 | 函数类型(如 func(int) int) |
存储可调用的函数,需类型一致。 | 策略模式、动态策略选择 |
| 接口数组 | interface{} |
存储任意类型值,需类型断言处理。 | 动态数据存储、异构数据集合 |
| 管道数组 | 通道(如 chan int) |
管理多个通道的通信,需 goroutine 协作。 |
多线程通信、任务队列管理 |
注意事项
- 函数数组:确保所有函数签名一致,否则编译报错。
- 接口数组:使用类型断言时需处理
nil或类型不匹配的情况,避免运行时错误。 - 管道数组:通道使用后需关闭,避免资源泄漏;非缓冲通道需注意阻塞问题。
浙公网安备 33010602011771号