如果你想在一个切片上有一个方法来减少它,定义MyStruct
为T
的切片:
type MyType[T any] []T
func (m MyType[T]) Reduce(init T, fnReduce func(acc, elem T) (result T)) T {
res := init
for _, v := range m {
res = fnReduce(res, v)
}
return res
}
这里有一个关于Playground的例子.
如果您需要能够将切片本身之外的其他字段添加到MyStruct
,则具有包含切片的字段的 struct 也是一个选项.(New
func用于从包外部填充私有切片字段.
func NewMyType[T any](sl []T) MyType[T] {
return MyType[T]{sl: sl}
}
type MyType[T any] struct {
sl []T
}
func (m MyType[T]) Reduce(init T, fnReduce func(acc, elem T) (result T)) T {
res := init
for _, v := range m.sl {
res = fnReduce(res, v)
}
return res
}
关于 comments 中所述的问题:
- 第一个 idea 是,每当确定需要减少数据时,就调用Reduced函数.如果有一个地方我们知道数据是Slice类型的,那么这就行得通.如果从来不是这样(所有代码都是通用的),那么看看选项2).
func reduce[T any](sl []T, init T, fnReduce func(acc, elem T) (result T)) T {
res := init
for _, v := range sl {
res = fnReduce(res, v)
}
return res
}
- 第二个 idea 是拥有一个针对不同数据类型不同实现的老式接口.
type MyI[T any] interface {
Reduce(init T, reduce func(acc, elem T) (result T)) T
}
type MySliceType[T any] struct {
data []T
}
func (m MySliceType[T]) Reduce(init T, reduce func(acc, elem T) T) T {
res := init
for _, v := range m.data {
res = reduce(res, v)
}
return res
}
type MyType[T any] struct {
data T
}
func (m MyType[T]) Reduce( T, func(acc, elem T) T) T {
return m.data
}
我们这里有一个常见的Reduce
函数,以防我们没有切片,它只返回m.data
.如果我们有一个切片,它实际上应用了REDUTE函数.
(这个例子没有太多意义,但我希望这个 idea 能被理解.)