注意:我正在将这个问题编辑成一个具体示例,说明为什么要这样做,这就是为什么某些答案在上下文中可能不再有意义的原因。
我正在编写一些代码,以传递来自输入的数据。数据采用标签的形式,这些标签具有一个标识符,该标识符标识它们所包含的是哪种数据,然后是该数据。
不幸的是,我无法控制输入,并且事先也不知道它将包含哪些标记,一个可能是int,另一个可能是字符串,而另一个可能是int数组。
当我需要处理所有相同类型的标签(例如,如果我有一部分标签)或接受或返回标签的函数时,就会出现问题。
到目前为止,我所看到的解决方案是使用一个空接口定义切片/函数,这将使我能够这样做,但是这是不可取的,因为它不会向使用该软件包的其他人告知任何内容类型是预期的,而且也有点违反了首先使用类型化语言的观点。
不过,接口似乎是这里的解决方案,我很想拥有一个Tag
接口来传递,尽管我需要在它们上定义方法,但确实需要,而且实际上并不需要它们。
我当前的解决方案如下
type Tag interface{
implementTag()
}
type TagInt int
func (tag TagInt) implementTag() {}
type TagString string
func (tag TagInt) implementTag() {}
虽然这确实可以解决我的问题,但是仅定义虚拟方法是很错误的。
所以我的问题总结如下:是否可以通过任何方式定义某物为Tag
而不必定义伪方法?
答案 0 :(得分:3)
现在想制作一个既可以容纳t1又可以容纳t2但又不能容纳其他任何东西的切片。
您不能那样做。抱歉。
答案 1 :(得分:1)
您可以将[]interface{}
用于“任何类型的切片”,但是由您决定使用类型断言和/或类型开关来发现该切片成员的实际运行时类型。
现在想制作一个既可以容纳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
}
如果您想要数据类型与其方法(即对象)之间的紧密结合,那么将其作为对象的方法又有什么错呢?