第2期-cmp.Ordered+类型推断+刻意未支持的特性

赞助

本课程由弘舟职擎赞助支持, 此网站提供自动化评测、AI模拟笔试和面试工具, 后期会有更多更强大的工具开发出来,请百度搜索'弘舟职擎模拟面试', 请大家关注和支持, 谢谢!

cmp.Ordered 与 comparable的对比

解决手写和遗忘地狱

上期结尾我留了个坑------comparable 只管判等、不管比大小。这期就把比大小的坑填上

golang 复制代码
type MyComparable interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint8 | ~int32 | ~string | float64
}


import cmp
func Max[T com.Ordered](a, b T) T {}

对比

能力 comparable cmp.Ordered
==/ != ✅ ✅
结构体/指针 ✅ ❌
字符串、数字 ✅ ✅

com.Ordered自定义struct怎么支持排序?

golang 复制代码
type User struct{
    Name string
    Age int
}
func Less(a,b User) bool {
    if a.Age <= b.Age {
        return true
    }
    return false
}

func SortUser[T any](users []T, less func(a, b T) bool) {
    ///
}

类型怎么推断的?

实参类型推断
golang 复制代码
func Index[T comparable](haystack []T, needle T) int {}
Index([]int{1, 2, 3}, 2) // 返回1
// []T => []int => T = int
范型约束推断
golang 复制代码
type SliceConstraint[E any] interface{
    ~[]E
}
func First[E any, S SliceConstraint[E]](s S) E {}

First([]int{1, 2, 3}) // []int -> S

~[]E - []int => E = int
无法隐式推断
golang 复制代码
func New[T any]() *T{
    return new(T)
}
p := New[int]()
// p := New() 
常量未类型化
golang 复制代码
type SmallInt interface{~uint8}
func SmallMax[T SmallInt](a, b T) T{...}
SmallMax(5, 10) // 编译错误, 5=> int
// 1. 强制类型转换
SmallMax(uint(5), uint(10))
// 2. 指定类型实参调用
SmallMax[uint8](5, 10)

Go 特意不做

Java /C Sharp 类型擦除 VS Go单态、Cpp 模板实例化

为什么这么克制?三个字:可读性。泛型方法语法复杂、推断负担重;运算符重载破坏可读性;类型特化让编译模型复杂、代码膨胀。最后补一个关键背景:Java 用类型擦除,编译后变 Object,运行时强转,基本类型要装箱;Go 用单态化,给每个类型参数生成一份特化代码,运行时零转换零装箱,代价是代码体积可能膨胀。这也解释了为什么 Go 不做 C++ 那套------单态化已经承担了按类型生成代码的成本。记四个不做:泛型方法、可变类型参数、运算符重载、类型特化/元编程,再加没有方法链语法。

四不做

不支持范型方法
golang 复制代码
type Stack[T any] struct {items []T}
func (s *Stack[T]) Push(v T) {} // 支持
// func (s *Stack[T]) Map[U any](f func(T) U) []U {} // 不支持
// Java : public <U> Box<U> map(...)
不支持可变类型参数 + 运算符重载
没有类型特化 / 模板元编程(C++特性)
cpp 复制代码
// C++: 全特化, bool单独一份实现
template <> struct Printer<bool> {....}
// go只有一份通用实现, 所有类型共用
没有方法链语法糖
Java 复制代码
// Java: box.map(...).map(...).count()
// Go: 只能独立函数调用

完整合集请看

相关推荐
afumu1 小时前
Go 写一个只监听 127.0.0.1 的控制服务:鉴权、白名单、危险命令拦截
后端·安全·go
johnjincaaaa2 小时前
猿人学第 18 题「jsvmp 洞察先机」逆向通关实录
javascript·后端
用户4702784004052 小时前
C语言编译与链接
后端·开源
你三大爷2 小时前
从 Hessian 迁移到 protostuff:深嵌套模型反序列化耗时与高并发类加载锁的根治实战
后端·架构
IT枫斗者枫哥2 小时前
子线程断言失败,JUnit 为什么还显示通过?
java·后端
stark张宇3 小时前
Vibe Coding 入门实战:用 Claude Code 跑通 AI 产品开发流程(上)
后端·claude·vibecoding
考虑考虑4 小时前
JDK27中的Set.ofLazy
java·后端·java ee
乌暮6 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
我不会起名字3226 小时前
未接入最终读上限的参数:`websocketMaxMsgLen` 与 12.5 倍差距
后端·websocket·go·即时通讯·im·故障排查
一条Go7 小时前
接收方合并去重:同一个人为什么只该收到一次通知
后端·架构·github