【问题标题】:Mapping concrete types映射具体类型
【发布时间】:2018-11-16 17:24:56
【问题描述】:

定义map[type]interface{} 之类的惯用方式是什么?

据我所知,type(作为关键字)不是可比的,因此不能用作地图中的键。也许我走错路了,所以我会接受任何建议。

TL;DR;

示例动机

假设在应用模型中,我有一个名为 Persontype,存储在一个名为 "person" 的 tablerdbms 的强>。

如果我想将实体对象 Person 链接到 表名。根据定义,事情不会在一起,所以避免用“非自然相关”污染 Person 结构是明智的(这是我基于 java-OO 的思想出现的地方)[pointer|value]-recieve 方法,所以地图可以在这里派上用场,对吧? (地图非常适合将来自不同世界或场景的事物关联起来,对吧?)

var tableNameByType map[type]string = map[type]string{
      Person: "person",
}

这个语句导致编译器对我大喊大叫,抱怨expected type, found 'type'。我试过用 used 代替 type、interface{} 和 struct,没有更好的结果。

提前感谢您花时间阅读我。

【问题讨论】:

    标签: go types maps


    【解决方案1】:

    使用reflect.Type 作为键:

    var tableNameByType map[reflect.Type]string = map[reflect.Type]string{
        reflect.TypeOf(Person{}): "person",
    }
    

    您可以使用以下方法获取类型的名称:

    name := tableNameByType[reflect.TypeOf(Person{})]
    

    ... 或值 v 的名称使用:

    name := tableNameByType[reflect.ValueOf(v).Type()]
    

    您可以通过将上述代码中的reflect.TypeOf(Person{}) 替换为reflect.TypeOf((*Person)(nil)).Elem() 来避免实例化结构值。

    【讨论】:

    • 是一个很好的解决方法!我想知道是否没有办法避免实例化给定类型的新结构(Person{})以获取类型?在这种情况下,推荐的方法是将 Person 类型的内部结构实例化(即在 Universe 块 golang 中但不是公共的)作为“类型的实时表示”?
    • 感谢@ThunderCat!您分享的非常有价值的信息!不知道 reflect.TypeOf((*Person)(nil)).Elem() 是哪种 vuddu 魔法,但感谢您的想法!
    • 让我们称这种技术为“基于生活表现的类型”吧:D。您需要创建给定类型(指针或值)的实例才能获取类型。
    • 请允许我将这个问题保持一段时间(以便能够获得更多答案)。如果没有为这个问题提供更多信息,这将是正确的答案。因为“基于生活表示的类型”是映射类型的惯用方式(直到 golang-dev-team 实现“原样”类型的比较)
    猜你喜欢
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 2018-12-21
    相关资源
    最近更新 更多