3 回答
TA贡献1813条经验 获得超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条经验 获得超7个赞
wondered, if this can be done by implementing an interface
当然可以。
我不会假装提供正确的惯用方式。但从你的说法来看,所有这些类型都可以归纳为一个IDer
接口。
为此,他们必须实现一个定义为 的接口type IDer interface { ID() int }
。ID()
必须为每个结构类型实现此方法。使用通用的兼容实现,您可以定义 a并将map[int]IDer
其放入其中Invoice
,只要它兼容即可。Booking
Project
为了防止代码重复,您可以定义一个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条经验 获得超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
}
上面的示例结合了 @mh-cbon 的 IDer 接口和跟踪最后添加的 Ider 的能力。
domain然后,只要任何对象实现了该接口,就可以将其与它们一起使用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 关注
- 136 浏览
添加回答
举报