Golang 基础06 接口interface

接口是一组函数声明,当某个对象实现了接口声明的函数就作为实现了接口,接口的实现是隐式的

Go 复制代码
// Shape 是接口类型: 任何实现了这两个方法的类型都自动满足它, 无需显式声明(隐式实现)。
type Shape interface { // 接口只描述行为, 不描述数据
	Area() float64      // 面积方法
	Perimeter() float64 // 周长方法
} // Shape 定义结束

// Rect 矩形, 通过值接收者方法实现 Shape。
type Rect struct { // 结构体实现接口
	W float64 // 宽
	H float64 // 高
} // Rect 定义结束

// Area 计算矩形面积, 实现 Shape。
// 参数/接收者 r: 矩形值副本。
// 返回: 面积。
func (r Rect) Area() float64 { // 满足 Shape.Area
	return r.W * r.H // 宽乘高
} // 方法结束

// Perimeter 计算矩形周长, 实现 Shape。
// 参数/接收者 r: 矩形值副本。
// 返回: 周长。
func (r Rect) Perimeter() float64 { // 满足 Shape.Perimeter
	return 2 * (r.W + r.H) // 两倍的(宽 + 高)
} // 方法结束

// Circle 圆, 同样实现 Shape。
type Circle struct { // 结构体实现接口
	R float64 // 半径
} // Circle 定义结束

// Area 计算圆面积, 实现 Shape。
// 参数/接收者 c: 圆值副本。
// 返回: 面积。
func (c Circle) Area() float64 { // 满足 Shape.Area
	return math.Pi * c.R * c.R // πr²
} // 方法结束

// Perimeter 计算圆周长, 实现 Shape。
// 参数/接收者 c: 圆值副本。
// 返回: 周长。
func (c Circle) Perimeter() float64 { // 满足 Shape.Perimeter
	return 2 * math.Pi * c.R // 2πr
} // 方法结束

当一个函数的形参要求的是接口Shape 的时候,我们就可以传递任意实现该接口的类型了如Circle和Rect,都可以作为合法参数传递

Go 复制代码
// TotalArea 演示面向接口的多态: 任何满足 Shape 的值都能传进来。
// 参数 shapes: 由多个 Shape 实现组成的切片。
// 返回: 所有图形面积之和。
func TotalArea(shapes ...Shape) float64 { // 参数是接口切片
	total := 0.0               // 累加器
	for _, s := range shapes { // 遍历接口值
		total += s.Area() // 动态派发: 运行时按动态类型查找方法
	} // range 结束
	return total // 返回总面积
} // 函数结束

同时interface{}和any作为一个接口作为参数的时候,可以在函数的内部进行断言判断类型是什么

语法格式是:对象.(类型)。switch语句可以使用对象.(type)然后case具体的类型做判断

Go 复制代码
func main() {
	var u any
	//var u2 interface{}
	u = "123"

	defer func() {
		if recover() != nil {
			fmt.Println("panic")
			fmt.Println("断言失败")
		}
	}()
	if u.(string) != "" {
		fmt.Println("断言success")
	}

}


类型断言的经典安全形式是v, ok := x.(T),v是断言后确定的值

对于任意数值切片求和,演示泛型函数与类型参数

既然是求和函数,接收参数是限定在int float这几个里面的。但是又不能每一个类型都单独的去写一个求和,所以这里就是用类型参数约束

Go 复制代码
type Tnumber interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64
}

func Sum[t Tnumber](numbers []t) t {
	var sum t
	for _, number := range numbers {
		sum += number
	}
	return sum
}

func main() {
	fmt.Println(Sum([]int{1, -2, 3, 4, 5}))
}
相关推荐
小小张说故事14 分钟前
Python 的 str 为什么设计成不可变?拆开字符串驻留、字符串池,以及 += 拼接到底慢在哪
后端·python
_冷眸_23 分钟前
Python 调用大模型 API:最小请求、Base URL 和 401/404 排查
开发语言·人工智能·python
AI架构师之家24 分钟前
我把 Hermes 这匹"马"养了两周,它干了一件让我有点发毛的事
后端
dpharness31 分钟前
块协议用了两周,我把九个坑按顺序记下来了
后端
niucloud-admin34 分钟前
NIUCLOUD PHP SAAS上门家政使用文档:服务保障
java·开发语言·php
加宝的起点雷达42 分钟前
跑了两周的信号日报,我把降级链改了四次
人工智能·后端
IT枫斗者枫哥1 小时前
CompletableFuture失败后返回空列表:异常没了,业务含义也变了
java·后端
Gopher_HBo1 小时前
opentelemetrySDK源码解析
后端
熊猫钓鱼>_>1 小时前
鸿蒙 PC 三方库适配复盘:libfvad 1.0 —— 把 WebRTC VAD 做成能装进采集链路的静态库
服务器·开发语言·华为·harmonyos·openharmony·适配·鸿蒙pc
UrbanJazzerati1 小时前
AutoHotkey v2 零基础快速入门 Part 10:给路线回放添加高精度计时,理解累计延迟与路线一致性
后端