在结构中使用通用切片字段

我们希望拥有


type ResponseListDataPayload struct {

    List     []*interface{} `json:"list"` //generic

    TotalCnt int64          `json:"totalCnt"`

    Page     int64          `json:"page"`

    Step     int64          `json:"step"`

}

并且可以接受List[]*model.SomeModel{}


queryResults := []*model.SomeModel{}

resposeResult := &ResponseListDataPayload{

    List:     queryResults,

    TotalCnt: cnt,

    Page:     pageInt,

    Step:     stepInt,

}

或[]*model.AnotherModel{}


queryResults := []*model.AnotherModel{}

resposeResult := &ResponseListDataPayload{

    List:     queryResults,

    TotalCnt: cnt,

    Page:     pageInt,

    Step:     stepInt,

}

这在Java中非常简单,这在Go中可能吗?


aluckdog
浏览 71回答 2
2回答

慕尼黑5688855

前往 1.18您现在可以拥有参数化结构:type ResponseListDataPayload[T any] struct {&nbsp; &nbsp; List&nbsp; &nbsp; &nbsp;[]T&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `json:"list"` //generic&nbsp; &nbsp; TotalCnt int64&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `json:"totalCnt"`&nbsp; &nbsp; Page&nbsp; &nbsp; &nbsp;int64&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `json:"page"`&nbsp; &nbsp; Step&nbsp; &nbsp; &nbsp;int64&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `json:"step"`}请记住,泛型结构必须使用显式类型参数进行实例化:queryResults := []*model.SomeModel{}responseResult := &ResponseListDataPayload[*model.SomeModel]{&nbsp; &nbsp; List:&nbsp; &nbsp; &nbsp;queryResults,&nbsp; &nbsp; // other fields}如果你想进一步提高代码重用率,并“泛化”结构初始化,你可以使用构造函数。函数可以利用类型推断来省略写出类型参数:// add to func signature other arguments as neededfunc NewResponseFor[T any](list []T) *ResponseListDataPayload[T] {&nbsp; &nbsp; return &ResponseListDataPayload[T]{ List: list }}并将其用作:queryResults := // some query resultsresponseResult := NewResponseFor(queryResults)示例:https://gotipplay.golang.org/p/jYTHegaeubR前往 1.17 及以下这在围棋中是可能的吗?不,实际上不是泛型类型,它只是一个具有空方法集的接口。interface{}形式上,您可以为其分配任何具体值,因为可赋值性要求值的方法集是接口方法集的超集,并且任何集都是空集的超集 ()。∅它与像Java这样的参数化类型不是一回事,因此在Go中不能分配给。List<T>[]Foo[]interface{}您必须在循环中处理单个元素:var m []*model.anotherModel// populate mfor _, v := range m {&nbsp; &nbsp; resp.List = append(resp.List, v)}同样,不要使用指向空接口 的指针。请改用。*interface{}interface{}如果您的目标只是序列化 JSON(基于结构上是否存在标记),则可以将字段声明为,并且出于上述原因,您可以将任一切片值分配给它。从而避免了额外的切片操作。然后,json 包将根据 中框出的具体值进行序列化。Listinterface{}interface{}

MMTTMM

在 Go 1.18 中,您将能够使用真正的 go 泛型来执行类似操作:func convert[S any](src []S) []interface{} {&nbsp; &nbsp; dst := make([]interface{}, 0, len(src))&nbsp; &nbsp; for _, v := range src {&nbsp; &nbsp; &nbsp; &nbsp; dst = append(dst, v)&nbsp; &nbsp; }&nbsp; &nbsp; return dst}//...resp.List = convert(m)但是,在 1.18 发布并且更多的代码库包含泛型之前,您仍然需要手动进行转换。就像大家说的,不要使用.*interface{}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go