Golang Go语言中如何实现 Python 中的 super?
Golang Go语言中如何实现 Python 中的 super?
python 中类似的需求很容易实现.
from abc import ABC
class Foooooo(ABC):
def test_method(self):
pass
class Foo(Foooooo):
def test_method(self):
super().test_method()
print("im in Foo")
class FooMixin(Foooooo):
def test_method(self):
super().test_method()
print("im in FooMixin")
class FooMixin2(Foooooo):
def test_method(self):
super().test_method()
print("im in FooMixin2")
class FooSubCls(Foo, FooMixin, FooMixin2):
def test_method(self):
super().test_method()
print("im in FooSubCls")
FooSubCls().test_method()
我可以添加无数个 test_method 这个在 django 中尤其常见. 请问 在 go 中如何实现类似功能? 手动指定的话, 可能得把整个继承关系梳理一遍,否则可能造成某个方法执行了两遍.
提前表示感谢.
更多关于Golang Go语言中如何实现 Python 中的 super?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
冇继承,你可以组合一下
更多关于Golang Go语言中如何实现 Python 中的 super?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
没继承,你这个问题本质属于多态的使用,struct 的组合能实现继承而无法实现多态
go 使用 interface 实现多态,写过 java 的不会陌生,虽然 java 万物皆类,但生产也提倡使用接口
你的代码可以这样写:
type test interface {
test_method ()
}
type Foo struct {
}
func(f *Foo )test_method{
print(“im in Foo”)
}
type Foo1 struct {
}
func(f *Foo1 )test_method{
print(“im in Foo1”)
}
这样,foo 和 foo1 都实现了 test 接口,foo 和 foo1 的实例(对象)都可以赋值给 test 接口,调用 test_method 时根据接口持有的类型,去调用该类型实现的方法,实现多态
func main(){
var t test
t = &Foo{}
t.test_method() //"im in Foo"
t = &Foo1{}
t.test_method() //“im in Foo1”
}
比较典型的是标准库 io.writer 和 io.reader 接口,不管是文件,日志,http resp , 都可以直接作为参数传递实现多态。
还有 gin 的 bind 函数,实现了一个函数解析所有类型的 http 请求参数
丢掉继承, 忘掉 OO, 拥抱更纯粹的编程吧
感谢回复,我想表达的是 python 中的 super 如何在 golang 中实现.
super 可以在多重继承中自动找到他的父类.
下图 实际上是可以无限扩展的, 但是在 go 中, 似乎需要手动指定调用的是哪个类(结构体)中的方法. 但是在 python 中,不需要在意这些.只要调用 super 就可以了.

你还想着那一套你就永远会觉得 go 别扭写不好。go 里面只有组合,没有继承。接口只能被实现,功能代码只能被互相组合。
5 楼说了,答案是没法实现,只能用组合和接口替代
而且父子继承本身就已被证明不是最优方案,经历几十年发展的 java 已经事实上在生产中抛弃了,不必强求这样实现把
确实有很多人尝试把自己在其他语言中用过的,觉得不错的功能转移到 Go 语言来用,但这些方法通常不符合 Go 语言的思想。
一种情况是,重新去阅读并理解 Go 语言的设计思想,拥抱 Go 语言。
还有一种情况就是骂 Go 语言什么垃圾语言,没法用,殊不知是自己的思想早已被禁锢,无法接纳新的理念。
声明一个 interface Foo{test_method()},然后用一个切片或者链表之类的
foos := []Foo{Foo1,Foo2,Foo3}
for _,fn:=range foos{
fn.test_method()
}
当然这样是能实现你说的,不过不清楚具体需求是啥。。。
另外忘记继承,忘记 OO 吧。。。
其实 super().method(*args)本质上就是 super(self.class, self).method(*args), python2 早期版本没 super 时也是通过父类.method(self, *args)这种写法显性调用的, 一直到 2.5 还有很多人这么写的, 习惯这种写法的 pythonist 可能反而更喜欢 go 这种方式吧, 比较清晰直白
首先搞清楚是否需要实现,这是一个好的设计吗?抽离本质对应 go 是怎样的实现?
super() 的本质不是 super(self.class, self) 而是 super(<该代码所在类>, self)
# super(self.class, self) 是会递归调用自身而爆 call stack 的。
实际上 super 主要解决的问题是 Diamond problem,Python 给出的答案是生成 MRO 顺序,利用了 Python 重度依赖运行时反射(内省)的特性。
Go 给出的答案是不继承
语言即思维方式。
已经说过多少次,不要用中文的思维去学英文
看下 Rosetta Stone® 这套自然语言学习软件的做法:根本不给你任何母语提示,直接把你丢到待学习语言环境中去,随着 “物的指示与称呼” 而启发性地学会语言 —— 如同一名婴儿学会自己的母语。
同样,学习新的编程语言不要拿旧的去套了。
顺便有一个概念叫 “负迁移”
如果新旧两种语言在某方面有形式上的相似性,那很容易跑偏
如果当初抛弃了汉字,换上了纯拼音,那中国人说英语的口音问题就比得上印度人说英语了。
可以可以继续努力.
在Go语言中,没有直接等同于Python中super()
的内建函数,因为Go语言在面向对象编程方面采用了不同的设计哲学。Python中的super()
主要用于调用父类的方法,而Go语言更强调组合而非继承,并且其类型系统不允许动态地查找父类方法。
不过,在Go中,你可以通过显式地调用父类型的方法来实现类似super()
的功能。以下是一个简单的例子,展示了如何在Go中模拟这种行为:
package main
import "fmt"
type Base struct{}
func (b *Base) Greet() {
fmt.Println("Hello from Base")
}
type Derived struct {
Base
}
func (d *Derived) Greet() {
// 调用父类型的方法
d.Base.Greet()
fmt.Println("Hello from Derived")
}
func main() {
d := &Derived{}
d.Greet()
}
在这个例子中,Derived
类型嵌入了Base
类型,这样Derived
就拥有了Base
的所有方法。通过d.Base.Greet()
显式地调用了Base
类型的Greet
方法,这在功能上与Python中的super().greet()
类似。
需要注意的是,Go的这种方法依赖于编译时的类型嵌入和静态解析,与Python中基于动态查找的super()
机制有本质区别。在设计Go程序时,应充分利用Go的类型系统和组合特性,以实现清晰、高效且易于维护的代码。