没有方法的多态性

时间:2019-02-21 15:05:10

标签: go polymorphism

注意:我正在将这个问题编辑成一个具体示例,说明为什么要这样做,这就是为什么某些答案在上下文中可能不再有意义的原因。

我正在编写一些代码,以传递来自输入的数据。数据采用标签的形式,这些标签具有一个标识符,该标识符标识它们所包含的是哪种数据,然后是该数据。

不幸的是,我无法控制输入,并且事先也不知道它将包含哪些标记,一个可能是int,另一个可能是字符串,而另一个可能是int数组。

当我需要处理所有相同类型的标签(例如,如果我有一部分标签)或接受或返回标签的函数时,就会出现问题。

到目前为止,我所看到的解决方案是使用一个空接口定义切片/函数,这将使我能够这样做,但是这是不可取的,因为它不会向使用该软件包的其他人告知任何内容类型是预期的,而且也有点违反了首先使用类型化语言的观点。

不过,接口似乎是这里的解决方案,我很想拥有一个Tag接口来传递,尽管我需要在它们上定义方法,但确实需要,而且实际上并不需要它们。

我当前的解决方案如下

type Tag interface{
    implementTag()
}

type TagInt int
func (tag TagInt) implementTag() {}

type TagString string
func (tag TagInt) implementTag() {}

虽然这确实可以解决我的问题,但是仅定义虚拟方法是很错误的。

所以我的问题总结如下:是否可以通过任何方式定义某物为Tag而不必定义伪方法?

3 个答案:

答案 0 :(得分:3)

  

现在想制作一个既可以容纳t1又可以容纳t2但又不能容纳其他任何东西的切片。

您不能那样做。抱歉。

答案 1 :(得分:1)

您可以将[]interface{}用于“任何类型的切片”,但是由您决定使用类型断言和/或类型开关来发现该切片成员的实际运行时类型。

Tour of Go

中了解有关空接口的更多信息
  

现在想制作一个既可以容纳t1又可以容纳t2但没有任何东西的切片   其他。

这是一个非常不寻常的要求,您在Go中不太可能需要此。但是您也可以使用以下方法进行自己的歧视性联合:

type item struct {
  typeSelector int
  t1Value t1
  t2Value t2
}

然后使用[]item,在运行时检查typeSelector,以查看填充了哪个值。

或者,您甚至可以使用*t1*t2并让nil表示“此字段中没有值”。

答案 2 :(得分:1)

在您的方案中,我将接受带有空接口的参数中的任何类型,然后在内部使用类型断言来确认它是您想要的类型。

if t1, ok := interfaceInput.(t1); !ok{
    // handle it being the wrong type here
    return
}

如果您想要数据类型与其方法(即对象)之间的紧密结合,那么将其作为对象的方法又有什么错呢?