去虚函数模拟
go virtual function simulation
在 go 中是否存在一些实现虚函数行为的技巧?我有以下示例。
package main
import "fmt"
type A struct {
}
type B struct {
*A
}
func (this *A) Do() {
fmt.Println("IM DO")
this.DoVirtual()
}
func (this *A) DoVirtual() {
fmt.Println("IM DoVirtual Default implementation")
}
func (this *B) DoVirtual() {
fmt.Println("IM DoVirtual B implementation")
}
func main() {
a := &A{}
a.Do()
fmt.Println("----")
b := &B{}
b.DoVirtual()
b.Do() // How to make here B.DoVirtual call
}
最后一个 Do() 调用也使用默认的 DoVirtual 实现,但实际上不是我想要的。原因是 go lang iheritance 模型:this *B 和 this *A 在这种情况下是不同的指针,但我想知道是否有可能对上次调用中的 DoVirtual 将从 B class。
当编译器选择 func (this *A) Do() {
时,封闭的 B 已经消失,无法再访问。 Go 不支持 is-a 结构,只支持 has-a(组合)。如果实现 func (this *B) Do() {
它将取代 *A 上的 Do()。当然,这不是你真正想要的。
我认为 Rob Pike Less is exponentially more 对实施和动机的最佳解释。
我的简单模拟,你可以用一些reflect
、代码生成甚至RPC来改进它。主要思想是添加一个虚拟方法 table,然后像 C++ 一样自己分派。
package main
import "fmt"
type A struct {
virFunDispatcher func(funAndParams ... interface{})
}
func newA() *A{
return &A{func(funAndParams ... interface{}){
fun := funAndParams[0].(string)
switch(fun){
case "DoVirtual":
fmt.Println("IM DoVirtual Default implementation")
}
}}
}
type B struct {
*A
}
func newB() *B{
a := A{func(funAndParams ... interface{}){
fun := funAndParams[0].(string)
switch(fun){
case "DoVirtual":
fmt.Println("IM DoVirtual B implementation")
}
}}
return &B{&a}
}
func (this *A) Do() {
fmt.Println("IM DO")
this.virFunDispatcher("DoVirtual")
}
func (this *A) DoVirtual() {
fmt.Println("IM DoVirtual Default implementation")
}
func (this *B) DoVirtual() {
fmt.Println("IM DoVirtual B implementation")
}
func main() {
a := newA()
a.Do()
fmt.Println("----")
b := newB()
b.DoVirtual()
b.Do() // How to make here B.DoVirtual call
}
在 go 中是否存在一些实现虚函数行为的技巧?我有以下示例。
package main
import "fmt"
type A struct {
}
type B struct {
*A
}
func (this *A) Do() {
fmt.Println("IM DO")
this.DoVirtual()
}
func (this *A) DoVirtual() {
fmt.Println("IM DoVirtual Default implementation")
}
func (this *B) DoVirtual() {
fmt.Println("IM DoVirtual B implementation")
}
func main() {
a := &A{}
a.Do()
fmt.Println("----")
b := &B{}
b.DoVirtual()
b.Do() // How to make here B.DoVirtual call
}
最后一个 Do() 调用也使用默认的 DoVirtual 实现,但实际上不是我想要的。原因是 go lang iheritance 模型:this *B 和 this *A 在这种情况下是不同的指针,但我想知道是否有可能对上次调用中的 DoVirtual 将从 B class。
当编译器选择 func (this *A) Do() {
时,封闭的 B 已经消失,无法再访问。 Go 不支持 is-a 结构,只支持 has-a(组合)。如果实现 func (this *B) Do() {
它将取代 *A 上的 Do()。当然,这不是你真正想要的。
我认为 Rob Pike Less is exponentially more 对实施和动机的最佳解释。
我的简单模拟,你可以用一些reflect
、代码生成甚至RPC来改进它。主要思想是添加一个虚拟方法 table,然后像 C++ 一样自己分派。
package main
import "fmt"
type A struct {
virFunDispatcher func(funAndParams ... interface{})
}
func newA() *A{
return &A{func(funAndParams ... interface{}){
fun := funAndParams[0].(string)
switch(fun){
case "DoVirtual":
fmt.Println("IM DoVirtual Default implementation")
}
}}
}
type B struct {
*A
}
func newB() *B{
a := A{func(funAndParams ... interface{}){
fun := funAndParams[0].(string)
switch(fun){
case "DoVirtual":
fmt.Println("IM DoVirtual B implementation")
}
}}
return &B{&a}
}
func (this *A) Do() {
fmt.Println("IM DO")
this.virFunDispatcher("DoVirtual")
}
func (this *A) DoVirtual() {
fmt.Println("IM DoVirtual Default implementation")
}
func (this *B) DoVirtual() {
fmt.Println("IM DoVirtual B implementation")
}
func main() {
a := newA()
a.Do()
fmt.Println("----")
b := newB()
b.DoVirtual()
b.Do() // How to make here B.DoVirtual call
}