package main
func To[T any](i interface{}) T {
return i.(T)
}
Method 指的是在结构体上的函数成员
👌
package main
type Container[T any] struct {
i T
}
func (c Container[T]) Get() T {
return c.i
}
🚫 方法上不支持再声明一个泛型(也许以后会支持)
func (c Container[T]) To[A any]() A {
return c.i.(A)
}
因为这个问题,我们就无法实现一个通用的泛型缓存包。
package main
type Cache struct {
m map[string]interface{}
}
// 这是泛型前的写法:每次获取了值还必须断言类型。
func (c *Cache) Get(key string) interface{} {
return c.m[key]
}
// 想要的语法:
// 这样我们在用起来就很舒服: `c.Get[User]("bysir")`,可惜不支持。
func (c *Cache) GetT[T any](key string) T {
return c.m[key].(T)
}
如果非得泛型不得不这样:
package main
type Cache[T any] struct {
m map[string]T
}
不过这就不通用了。
学习了语法,来看几个实际用途
package main
import "encoding/json"
func Unmarshal[T error](bs []byte) (t T, err error) {
err = json.Unmarshal(bs, &t)
return
}
func main() {
u, err := Unmarshal[User]([]byte(`{"name": "bysir"}`))
// 泛型前的写法 (能少写一行是一行):
var u User
err := json.Unmarshal(bs, &u)
}
泛型前
package main
func main() {
var err error = MyError{}
// 泛型前
var s MyError
if errors.As(err, &s) {
print(s.InnerMsg)
}
// 泛型后
if s, ok := ErrorAs[MyError](err); ok {
print(s.InnerMsg)
}
}
func ErrorAs[T error](err error) (t T, ok bool) {
ok = errors.As(err, &t)
return
}
坑有点大 不写了
推荐一个库,基本操作(比如上面提到的 errors.As)可以先去里面找找