gpt4 book ai didi

Go:类型切换断言中的这种多案例条件有什么问题?

转载 作者:数据小太阳 更新时间:2023-10-29 03:13:51 25 4
gpt4 key购买 nike

我的代码一般是这样的:

func BulkInsert(docs interface{}) {
switch data := docs.(type) {
case map[string] *model.SnapshotByConv, map[string] *model.UserSnapshotsMap:
for ver, _ := range data {
// other logics ...
}
case map[int64] map[string] *model.Delta:
for ver, _ := range data {
// other logics ...
}
}
}

然后在编译时出现错误:不能覆盖数据(类型接口(interface) {}),它由第一个 range 引发。

如果我在第一种情况下删除多个类型,这意味着将其保留为 case map[string] *model.SnapshotByConv:

然后编译错误就消失了,它是 wried,我需要对这两种类型进行完全相同的逻辑,那么为什么我不能将它们放在相同的 case 中?

请帮忙,谢谢。

我认为这里的情况与这里已经有答案的情况不同:golang multiple case in type switch ,它试图找到一种识别类型的方法,但我只是不想识别某些类型,只是在其上运行一些逻辑,我找不到一种优雅的方法来做到这一点。

最佳答案

如果案例枚举多种类型(就像您的示例中那样),变量的类型将不会缩小,因此在您的案例中它将是 interface{}。这就是您链接到的问题所说的内容,没有办法解决它。

要为两种不同类型的情况分派(dispatch)一些通用代码,您需要在两者之间引入一个接口(interface)。 (如果 Go 在某个时候引入泛型,这可能会改变,但从外观上看,这不会很快发生。)有几种方法可以做到这一点,这里是三个:

1 - 为您的 map 定义类型,并添加一个通用接口(interface)

不要直接使用映射,而是定义映射类型,并为其添加函数。

type SnapshotMap map[string]*model.SnapshotByConv
type UserSnapshotMap map[string]*model.UserSnapshotsMap

func (sm *SnapshotMap) DoLogic() {/*...*/}
func (usm *UserSnapshotMap) DoLogic() {/*...*/}

type LogicDoer interface {
DoLogic()
}

// ...

switch data := docs.(type) {
case LogicDoer:
data.DoLogic()
// ...
}

2 - 使 map 具有通用界面

不要创建指针映射,而是创建快照类型共享的接口(interface)映射。

type Snapshot interface {
LogicCommonToSnapshots()
}
var doc interface{}

// Somewhere else, this happens rather than a creating map[string]*Something
doc = make(map[string]Snapshot)

// ...

switch data := doc.(type) {
case map[string]Snapshot:
for ver, _ := range data {
ver.LogicCommonToSnapshots()
}
// ...
}

3 - 分解逻辑并使其回调到公共(public)接口(interface)

将 switch case 拆分为两个独立的 case,但将逻辑分解为一个可以对任一快照类型进行操作的函数。这样,您就不必重复逻辑。

type Snapshot interface {
LogicCommonToSnapshots()
}

func ComplexLogic(s Snapshot) {/*...*/}

switch data := doc.(type) {
case map[string] *model.SnapshotByConv:
for ver, _ := range data
ComplexLogic(ver)
}
case map[string] *model.UserSnapshotsMap:
for ver, _ := range data {
ComplexLogic(ver)
}
// ...
}

请注意,在所有这三种情况下,都有一个接口(interface)将公共(public)逻辑与逻辑作用的对象分开。您必须必要地在逻辑和对象之间引入动态绑定(bind)以完成您描述的内容,无论是通过接口(interface)还是通过例如创建一个捕获对象的匿名函数将传递给逻辑。

关于Go:类型切换断言中的这种多案例条件有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43017440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com