我在Go中有两个功能几乎相同。它们采用一段具有“ID”字段的结构,并将其重新排序为由该字段索引的地图。然后,他们将它附加到另一个结构的字段,该结构也由ID标识。
这两个函数的作用相同,但附加到struct中的两个不同的字段。我想让方法通用,但我不知道该怎么做。我希望它可以使用指针完成,但我不确定如何。
功能1:
func addPremiereDatesToMovies(m []Movie, pd []PremiereDate) ([]Movie, error) {
pds := make(map[int64][]PremiereDate)
// Key-index the premiere-date array for easier lookup
for _, value := range pd {
pds[value.Id] = append(pds[value.Id], value)
}
// Append premiere dates to movies where such exist
for key, value := range m {
if _, ok := pds[value.Id]; !ok { // <-- How to make this generic?
m[key].PremiereDates = []PremiereDate{}
continue
}
m[key].PremiereDates = pds[value.Id]
}
return m, nil
}
功能2:
func addGenresToMovies(m []Movie, g []Genre) ([]Movie, error) {
gs := make(map[int64][]Genre)
// Key-index the genre array for easier lookup
for _, value := range g {
gs[value.Id] = append(gs[value.Id], value)
}
// Append genres to movies where such exist
for key, value := range m {
if _, ok := gs[value.Id]; !ok { // <-- How to make this generic?
m[key].Genres = []Genre{}
continue
}
m[key].Genres = gs[value.Id]
}
return m, nil
}
看起来,它们看起来非常相似。我能够做到这一点,除了我无法弄清楚如何一般地描述第11行的“value.Id”字段。
谢谢。
答案 0 :(得分:3)
虽然我同意kostya将其作为单独的功能完全正常,但如果您想要为电影添加20多个项目,可能会变得不那么易于维护 - 例如cast
,{{1}你将留下20多个功能。
以下函数会将其压缩为一个函数,但您需要为要添加的每个字段添加不同的revenues_per_country
部分。
要使用它,只需将其取下当前的电话:
使用方法:
case
movies = addStuffToMovies(movies, genres)
您可以通过添加interface更进一步,然后通过// addStuffToMovies adds fields to a movie where the ID matches
func addStuffToMovies(movies []Movie, stuff interface{}) []Movie {
// Go through the movies list
for current, movie := range movies {
// check the type and append based on that
switch v := stuff.(type) {
// This is the section you'll need to duplicate for each type of field
case []Genre:
for _, item := range v {
// if it matches, append it to Genres
if item.Id == movie.Id {
movies[current].Genres = append(movies[current].Genres, item)
}
}
// This is the section you'll need to duplicate for each type of field
case []PremiereDate:
for _, item := range v {
// if it matches, append it to PremiereDates
if item.Id == movie.Id {
movies[current].PremiereDates = append(movies[current].PremiereDates, item)
}
}
}
}
return movies
}
,{stuff interface{}
之类的[]FieldInterface
取代GetID()
。 1}}而不是不同的GetType()
部分。我认为你仍然需要在某处进行类型检查以实际将其分配给电影。当上面的case
能够正常工作时,这可能会付出很多努力。