【问题标题】:Type switch from superset to subset interface type类型从超集切换到子集接口类型
【发布时间】:2021-05-24 01:47:52
【问题描述】:

我需要在内存存储中存储一个实现特定类型的对象。被存储对象的类型必须满足一个接口,该接口是被存储对象实现的接口的超集。

我想弄清楚的是,当我从商店中检索对象时,如何访问原始 [接口] 类型?从超集到子集的类型切换似乎是不可能的。

这里有一个示例代码,希望能让这更容易理解。

接口类型

type Object interface {
    UID() string
    Name() string
    Attrs() map[string]string
    Parent() string
}

type Entity interface {
    UID() string
    Name() string
    Attrs() map[string]string
}

type Node interface {
    Entity
}

type SpecialNode interface {
    Node
    ID() int
}

您可以看到Object 接口是Entity 接口的子集,即所有Objects 都自动实现Entity 接口,因此EntityObject 的超集。

接口的示例实现:

type node struct {
    Node
}

type specialNode struct {
    Node
    id int
}

func (n specialNode) ID() int {
    return n.id
}

type object struct {
    uid    string
    name   string
    attrs  map[string]string
    parent string
}

func (e object) UID() string              { return e.uid }
func (e object) Name() string             { return e.name }
func (e object) Attrs() map[string]string { return e.attrs }
func (e object) Parent() string           { return e.parent }

现在,这是一个示例main.go

package main

import "fmt"

func main() {
    o := object{
        uid:    "xyz",
        name:   "entName",
        attrs:  make(map[string]string),
        parent: "entParent",
    }

    n := node{
        Node: o,
    }

    sn := specialNode{
        Node: n,
        id:   100,
    }

    fmt.Printf("%#v\n", sn)
}

这会按预期打印以下内容:

main.specialNode{Node:main.node{Node:main.object{uid:"xyz", name:"entName", attrs:map[string]string{}, parent:"entParent"}}, id:100}

现在,我如何从sn 中“提取”object/Object?像这样sn.Node.(Object) 的类型切换是不可能的。 Go有什么办法可以做到这一点?

链接到playground

【问题讨论】:

  • 从 sn 中提取对象/对象是什么意思? sn.Node.Node 实际上是 Object 接口的实现
  • 我想从内存中检索对象,将它的类型切换为Object 类型并使用任何Object 方法。我不确定您所说的sn.Node.Node 是什么意思?
  • "从超集到子集的类型切换似乎是不可能的。"您只需要一个简单的类型转换:play.golang.org/p/Rms0yPArDLa

标签: go


【解决方案1】:

你必须把它转换成一个接口才能进行类型转换

Cannot type switch on non-interface value

o2:= interface{}(sn.Node.(node).Entity.(object))
var oo2 Object = o2.(Object)
fmt.Printf("%#v\n",oo2)

【讨论】:

  • 不需要interface{} 类型转换。 interface{} 类型实现所有接口。这会很好:sn.Node.(node).Entity.(Object)。如果您更正原始答案,我会接受它
猜你喜欢
  • 2013-04-08
  • 2012-09-27
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多