1 Star 1 Fork 0

笑笑独一人 / go-in-prod

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
simple_test.go 3.42 KB
一键复制 编辑 原始数据 按行查看 历史
wenzhou 提交于 2022-11-24 09:03 . 10分钟泛型
package generics
import (
"errors"
"fmt"
"strconv"
"testing"
)
/*
典型需求
1.标准数据结构 通用类型
2.复用业务代码 只有类型不同
3.类型安全校验
*/
func add(x, y float32) float32 {
return x + y
}
func addGeneral(x, y interface{}) interface{} {
switch ret := x.(type) {
case int:
return ret + y.(int)
case float32:
return ret + y.(float32)
default:
return nil
}
}
/*
泛型指定
1.类型
2.类型集合
*/
func addT[T int | int64 | float32 | float64](x, y T) T {
return x + y
}
/*
支持基础类型上扩展类型
*/
type MyInt int
func addT2[T ~int | ~int64 | ~float32 | ~float64](x, y T) T {
return x + y
}
/*
1.本质上类型是接口
2.预定义 any comparable
3.预计加入Ordered
4.一切接口皆可泛型
*/
type Number interface {
int | int64 | float32 | float64
}
func addNumber[T Number](x, y T) T {
return x + y
}
func printT[T any](x T) {
fmt.Println(x)
}
// error - Invalid operation: x == y (the operator == is not defined on T)
//func isEqualT2[T any](x, y T) bool {
// if x == y {
// return true
// } else {
// return false
// }
//}
func isEqualT[T comparable](x, y T) bool {
if x == y {
return true
} else {
return false
}
}
// error - Invalid operation: x >= y (the operator >= is not defined on T)
//func maxT2[T any](x, y T) T {
// if x >= y {
// return x
// } else {
// return y
// }
//}
type Ordered interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float32 | ~float64 |
~string
}
func maxT[T Ordered](x, y T) T {
if x >= y {
return x
} else {
return y
}
}
type MyT struct {
val int
}
func (t MyT) String() string {
return strconv.Itoa(t.val)
}
func makeStringT[T fmt.Stringer](x T) string {
return x.String()
}
/*
泛型不仅校验类型还校验范围
*/
// error - untyped int constant 1000
//func addT3[T int8](x T) T {
// return x + 1_000
//}
func addT4[T int8](x T) T {
return x + 100
}
/*
1.基于结构体的自定义
2.不支持结构体方法的泛型参数
*/
type MyStack[T any] struct {
vals []T
}
func (s *MyStack[T]) Pop() (T, error) {
l := len(s.vals)
if l == 0 {
var zero T
return zero, errors.New("empty stack")
}
v := s.vals[l-1]
s.vals = s.vals[:l-1]
return v, nil
}
func (s *MyStack[T]) Push(val T) {
s.vals = append(s.vals, val)
}
// error - Method cannot have type parameters
//
//func (s *MyStack[T]) ConvertAndPush[In any](val In, f func(x In) T) {
// s.vals = append(s.vals, f(val))
//}
func (s *MyStack[T]) Dump() {
fmt.Println("\n dump vals:")
for i := 0; i < len(s.vals); i++ {
fmt.Println(s.vals[i])
}
}
/*调用时类型推导*/
func TestAdd(t *testing.T) {
t.Log(add(1, 2))
t.Log(addGeneral(1, 2))
t.Log(addGeneral(float32(1.0), float32(2.0)))
//t.Log(addGeneral(1, "2")) error
t.Log(addT(1, 2))
t.Log(addT(2.0, 2.0))
//t.Log(addT(MyInt(1), MyInt(2))) // error type not exactly match
t.Log(addT2(MyInt(1), MyInt(2)))
t.Log(addNumber(2, 3))
t.Log(addNumber(3.0, 3.0))
printT(1)
printT("test1")
t.Log(isEqualT(1, 2))
t.Log(isEqualT(MyT{val: 1}, MyT{val: 2}))
t.Log(maxT(2, 3))
t.Log(maxT("3232", "24242"))
// t.Log(makeStringT(1)) //error - Type does not implement 'fmt.Stringer' as some methods are missing
t.Log(makeStringT(MyT{val: 1}))
s := MyStack[int]{make([]int, 0)}
s.Push(1)
s.Push(2)
s.Dump()
s.Pop()
s.Dump()
s2 := MyStack[string]{make([]string, 0)}
s2.Push("test1")
s2.Dump()
s.Pop()
s.Pop()
s.Dump()
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/wenzhou1219/go-in-prod.git
git@gitee.com:wenzhou1219/go-in-prod.git
wenzhou1219
go-in-prod
go-in-prod
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891