3 回答
TA貢獻1813條經(jīng)驗 獲得超2個贊
收集到所有信息后,我得出以下答案:
https://play.golang.org/p/3RAvclRacbh
(為了方便命名,我使用了“List”)
package main
import (
"fmt"
)
type Invoice struct{
Name string
Id int
}
// Interface to implement
type IDer interface {
ID() int
}
// Interface implementation for Invoice
func (i Invoice) ID() int { return i.Id }
type List struct {
Items map[int]IDer
last IDer
}
func (i *List) Add(index int, ider IDer) {
i.Items[index] = ider
i.last = ider
}
func (i *List) nextID() int {
if i.last == nil {
return 1
}
return i.last.ID() + 1
}
type Repository struct {
invoices List
}
func main() {
r := Repository{}
r.invoices = List{
Items: make(map[int]IDer),
}
i := Invoice{}
i.Name = "Test"
i.Id = 1
r.invoices.Add(1, i)
ia := r.invoices.Items[1].(Invoice)
fmt.Println(ia.Name)
fmt.Printf("Next ID: %d\n", r.invoices.nextID())
i2 := Invoice{}
i2.Name = "Test2"
i2.Id = r.invoices.nextID()
r.invoices.Add(i2.Id, i2)
ia2 := r.invoices.Items[i2.Id].(Invoice)
fmt.Println(ia2.Name)
fmt.Printf("Next ID: %d\n", r.invoices.nextID())
i3 := Invoice{}
i3.Name = "Test3"
i3.Id = r.invoices.nextID()
r.invoices.Add(i3.Id, i3)
ia3 := r.invoices.Items[i3.Id].(Invoice)
fmt.Println(ia3.Name)
fmt.Printf("Next ID: %d\n", r.invoices.nextID())
}
Test
Next ID: 2
Test2
Next ID: 3
Test3
Next ID: 4
Program exited.
TA貢獻1843條經(jīng)驗 獲得超7個贊
wondered, if this can be done by implementing an interface當然可以。
我不會假裝提供正確的慣用方式。但從你的說法來看,所有這些類型都可以歸納為一個IDer接口。
為此,他們必須實現(xiàn)一個定義為 的接口type IDer interface { ID() int }。ID()必須為每個結(jié)構(gòu)類型實現(xiàn)此方法。使用通用的兼容實現(xiàn),您可以定義 a并將map[int]IDer其放入其中Invoice,只要它兼容即可。BookingProject
為了防止代碼重復(fù),您可以定義一個type IDed struct { ID int}; func (i ID) int {return i.ID},并將其嵌入到您的類型中,例如type Invoice struct { IDed }等等。這樣做您仍然可以打電話var x Invoice; x.ID=1; someid := x.ID;
最后,您可以將映射定義為類型type mapOfID map[int]IDer并向其附加方法func (m mapOfID) DoSomethigWithIDers(){...}
TA貢獻1808條經(jīng)驗 獲得超4個贊
地圖本身在跟蹤“最后”項目方面做得很差,因為它不是其存儲或語義的一部分。解決這個問題的一種方法是跟蹤最后一個索引或domain添加到映射中的最后一個對象,以便計算下一個 id:
type IDer interface {
ID() int
}
type IDS struct {
m map[int]IDer
last IDer
}
func (i *IDS) Add(index int, ider IDer) {
i.m[index] = ider
i.last = ider
}
func (i *IDS) nextID() int {
if i.last == nil {
return 1
}
return i.last.ID() + 1
}
上面的示例結(jié)合了 @mh-cbon 的 IDer 接口和跟蹤最后添加的 Ider 的能力。
domain然后,只要任何對象實現(xiàn)了該接口,就可以將其與它們一起使用IDer:
type Invoice struct{}
func (i Invoice) ID() int { return 1 }
func main() {
ids := &IDS{
m: make(map[int]IDer),
}
ids.Add(1, Invoice{})
fmt.Printf("Next ID: %d\n", ids.nextID())
}
Next ID: 2
Program exited.
- 3 回答
- 0 關(guān)注
- 221 瀏覽
添加回答
舉報
