这篇没啥好讲的,个人学习笔记,纯引个流。
go
package main
import (
"fmt"
)
// TIP To run your code, right-click the code and select <b>Run</b>. Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.
type MyStruct interface {
~int | ~float32 // 支持所有底层类型是 int 或 float32(例如 MyInt,MyFloat)
}
func PrintValue[T MyStruct](v T) {
fmt.Println(v)
}
type MyInt int
type MyFloat float32
func PrintValue2[T int | float32](v T) {
fmt.Println(v)
}
/*
⚠️ 为什么 Go 要区分 T 和 ~T?
Go 的类型系统强调 "命名类型(named type)" vs "底层类型(underlying type)":
type MyInt int 是一个新类型,与 int 不等价(不能直接赋值给 int 变量,除非显式转换);
但在泛型中,你可能希望允许所有底层是整数的类型参与运算(比如写一个通用的 Add 函数);
~T 就是为了这种场景设计的 ------ "只要底层是 T,我就接受"。
*/
type CompareStruct[T comparable] struct {
num1 T
num2 T
}
/*
Go 1.22+ 内建了常用约束(无需 import):
comparable:支持 ==/!=
ordered:支持 <, >, <=, >=(即 int, float64, string 等)
*/
type Box[T any] struct{ value T }
// GetValue ✅ 泛型类型可以有普通方法d
func (b Box[T]) GetValue() T { return b.value }
/*
Go 1.25 移除了核心类型的设定
根据 Go 1.24 的规范,对类型参数为P T([T ~[]byte | string]) 的变量进行切片操作 (s[i:j]) 是不允许的,
因为 T 没有核心类型(具有多个底层类型),即使切片操作对[]byte和string本身都是合法的。
*/
func main() {
// instance 1
PrintValue(MyInt(32))
PrintValue(MyFloat(3.14))
// instance 2
PrintValue2(32)
PrintValue2(float32(3.14))
//PrintValue2(MyInt(32)) 不支持
//PrintValue2(MyFloat(3.14)) 不支持
// instance 3
st1 := CompareStruct[int]{
num1: 2,
num2: 3,
}
st2 := CompareStruct[int]{
num1: 3,
num2: 5,
}
if st1.num2 > st2.num2 {
fmt.Println("true")
} else {
fmt.Println("false")
}
// instance 4
box := Box[int]{
10000,
}
PrintValue(box.GetValue())
}