我有下面的代码尝试将嵌入结构分配给其父结构。有两套结构: guider
是父结构,datablock
从它扩展。方法 func put(x guider)
接受类型为 guider
的参数。当我传递 datablock
变量时它起作用。
另一种情况是mock
继承自zerolog.event
,但是在方法test(e zerolog.event)
上传递参数失败
我收到以下错误:
cannot use m (variable of type mock) as type zerolog.event in argument to test
为什么这两种情况的工作方式不同?我怎样才能让它们都工作?
package main import ( "fmt" "github.com/rs/zerolog" ) type Guider interface { Guid() string } type FSEntity struct { guid string } func (e FSEntity) Guid() string { return e.guid } func Put(x Guider) { fmt.Printf("%+vn", x) } type Mock struct { zerolog.Event } func Test(e zerolog.Event) { } //Child struct: type DataBlock struct { FSEntity data []byte } func main() { myVar := DataBlock{} myVar.guid = "test" myVar.data = []byte("moar test") Put(myVar) // it works m := Mock{} Test(m) // it doesn't work. cannot use m (variable of type Mock) as type zerolog.Event in argument to Test }
首先,有几个定义:
多态性是为不同类型的实体提供单一接口或使用单一符号来表示多种不同类型。
子类型(也称为子类型多态性或包含多态性)是类型多态性的一种形式,其中子类型是通过某种可替换性概念与另一种数据类型(超类型)相关的数据类型,这意味着程序元素(通常是子例程或函数) ,编写为对超类型的元素进行操作也可以对子类型的元素进行操作
在面向对象编程中,继承是将一个对象或类建立在另一个对象(基于原型的继承)或类(基于类的继承)之上的机制,并保留类似的实现。
对象组合和对象聚合是将对象或数据类型组合成更复杂的对象或数据类型的密切相关的方法。
Golang遵循组合优于继承原则,例如它不支持继承。所以当你说
模拟扩展自zerolog.Event
您实际上的意思是 Mock
包含 zerolog.Event
结构。
Golang实现多态的方式是interface
。所有实现某个接口的类型都可以在其位置上使用。这就是您使用 Guider
时看到的内容。
但是,它不适用于简单的结构。 zerolog.Event
是 Mock
内部的一个结构体。
因此,通常情况下,Test
函数应该接受某个接口作为参数,并且模拟事件和真实事件都应该实现该接口。然而,看起来zerolog并没有提供Event的接口。因此,您应该访问结构体的 Event
字段。 示例