gitalk
gitalk copied to clipboard
Go泛型不支持泛型方法,这是一个悲伤的故事
Go泛型不支持泛型方法,这是一个悲伤的故事
根据Go 泛型提案的描述,Go不支持泛型方法:No parameterized methods。主要原因Go泛型的处理是在编译的时候实现的,泛型方法在编译的时候,如果没有上下文的分析推断,很难判断泛型方案该如何实例化,甚至判断不了,导致目前(Go 1.18)Go实现中不支
错字
这也是促进哦把这几天看到的case总结的原因。
r如果是熟悉其它编程语言,
有一点点让人欣慰的是,Ian Lance Taylor和Ian Lance Taylor并没有把话说绝
有处笔误,应为 Ian Lance Taylor和Robert Griesemer
第一次试用也发现了这个限制,怎么也绕不开。我感觉Facilitator模式也没解决问题,只是把问题甩给了All函数:
func (q *Querier[T]) All(ctx context.Context) ([]T, error) {
// implementation
// 除非支持特化,否则这里怎么实现能够返回一个任意的[]T??
}
"泛型signleflight" -> "泛型singleflight"
其实可以用类似Haskell或者Rust的newtype pattern来凑活,而且由于interface不是单纯的类型类,有可能要当类似rust的trait object来用,所以这个问题其实不好解决。当你需要给一个已有的类型用复杂的带泛型的方法的时候,就把它“lift“到另外一个new type上,通过newtype的泛型来调用泛型方法。当你需要在一个对象上用多个不同的泛型,只需要类型转换一下(大多数情况下是指针,损耗不大)。
type Logic[T any] int
func (self *Logic[T]) sum(xs []T, ops Monoid[T]) T {
ans := ops.Zero()
for _, x := range xs {
ans = ops.Add(ans, x)
}
return ans
}
func TestCast() {
origin_obj := 0
logic := &origin_obj
// sum := (*Logic[int])(logic).sum
(*Logic[int])(logic).sum([]int{1, 2, 3}, new(MonoidInt))
(*Logic[string])(logic).sum([]string{"fst", "snd"}, new(MonoidString))
}
想的我头疼 只能换一种方法泛型了
var ( OK = Code(0, "success") IllegalArgument = Code(100400, "illegal argument") )
type ResponseCode struct {
Code int json:"code"
Msg string json:"msg"
}
func (code *ResponseCode)[T any] ToRsp() AppResponse[T anm] { return Create(code.Code, code.Msg) }
func Code(code int, msg string) *ResponseCode { return &ResponseCode{code, msg} }
func ToRsp[T any](code *ResponseCode) AppResponse[T] { return Create(code.Code, code.Msg) }
既然举了db的例子,这么做有个非常大的问题是违背了单例模式。比如想生成多个db但底层是一个实例就相当难做(因为每个泛型结构会被当成一个新的实例)。或者也可以投机取巧,在实例的工厂方法里增加一个成员,这个成员是指向底层操作数据库的单例对象的指针。为了保护单例,可以把这个对象做成一个私有接口(含private()空方法就行),别人在包外无法实现。但这样复杂度就相当高了
真的坑,没有这个能力很多地方做起来太过于麻烦了!