Golang Go语言中关于接口和面向对象问题的一点遐(扯)想(蛋)

发布于 1周前 作者 htzhanglong 来自 Go语言

Golang Go语言中关于接口和面向对象问题的一点遐(扯)想(蛋)

问题的起因是看到一种很奇怪的写法: 结构体 A 实现了接口 B,其中一个接口 B 嵌套了接口 C、D,另外有一个方法 Fun(),B 的引用是 b。 b.(interface{ Fun() }).Fun() 这里调用的是结构体 A 的方法 Fun()。

这里的问题就来了,这种写法比较奇怪,但是好歹算是正确的。如何保证它的正确性呢? 放在 Java 里肯定不行,因为 Java 是有类继承的,类的类型可以在子类父类间转换。这种写法只能在 Fun()只有一个实现的情况下才能保证正确性,然而 golang 其实也是有重写这个概念的。

查了一下发现,类型断言 v := varI.(T),其中 varI 只能是接口。或许是因为这个机制从而保证了上述写法的正确性。

请指正!


更多关于Golang Go语言中关于接口和面向对象问题的一点遐(扯)想(蛋)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

21 回复

和 java 的没啥关系,只要是名字参数都符合就可以转过去了,也没有啥基类派生类。。

更多关于Golang Go语言中关于接口和面向对象问题的一点遐(扯)想(蛋)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这种写法只能人为保证正确性,机制上只提供了一个 ok 返回值供判断

可以编译期判断 var _ A = new(B)

不知道为什么上来就又要面向对象…何必呢

其实就是懒得写一个 Fun 的接口了而已,为此丢了编译期检查,又不愿意判 ok 引入 panic 的风险 :doge:

不是,你把接口改成 B 也行。
我觉得这么写可能是因为阅读方便,原来的 B 接口有 N 多个方法,而你只用 B 接口中的几个方法,把他们组成一个接口,这样阅读性更好些。
不过我还是觉得这种写法不太自然

我理解能力差,没太看懂…能具体解释一下吗

go 的隐式实现接口的特性可以让它凭空实现一个含结构体方法的接口(所谓无中生妈),这种写法其实没卵用,或者说我现在还没有发现它有什么卵用。
go 用组合代替继承,可以实现重写。
后来想了想,其实重写和接口没关系。。。

什么叫接口嵌套接口

A 实现了接口 B,A 有一个实例叫 b
b.(B).Func() 么这不就是???

没看懂楼主想说什么……
本来 b 就可以直接 b.Func() 啊???

关键是这个:
b.(interface{ Fun() }).Fun()

go 里面也不行,
编译时无法保证 b 实现了 Fun() ,运行时如果 b 未实现 Fun() 会 panic。

最好这样处理下:

<br>_fun,ok:=b.(interface{ Fun() })<br>if !ok{<br> return fmt.ErrorF("")<br>}<br><a target="_blank" href="http://_fun.Fun" rel="nofollow noopener">_fun.Fun</a>()<br>

Fun 是 A 结构体的,类型为 B 的变量 b 即使实体是 A 也没法直接调到,所以才有那个匿名接口的类型断言

emmm,一般用 goland 写,goland 会自动检测这个方法有没有被实现。。。
你要是用 vscode 什么的确实会有这种问题。


但是 B 没实现 Func 的话,断言会失败啊。
所以 B 实现了 Func,那么断言之后调用 Func 还是 B 的 Func 吧?

没法保证,你要人肉保证

void*在 c 里面可以随便转成函数指针

看了最新的补充才看懂是在说什么……你们怎么就一下子明白了楼主的意思的???

语言表达能力有待提高……

“结构体 A 实现了接口 B ”,这句 ok
“其中一个接口 B 嵌套了接口 C、D ”,接口 B 就只有一个,“其中一个”似乎多余
“另外有一个方法 Fun()”,指代不明,究竟是 A 类型有 Fun 方法,还是 B 接口有 Fun 方法?
“ B 的引用是 b ”,意义不明,B 是一个接口类型,接口类型的引用是啥?是指“有一个变量叫 b,类型是 B ”?

第一段就不知所云,后面两段也不知道在说什么。

后面那个“最新发现”,怎么忽然就变成结构体的嵌套了。后面这不就是最基本的类型断言么,感觉就是学得太少想得太多而已。

感觉就是某种 down cast
那么为什么不 b.(A)呢?

b.(interface{ Fun() }).Fun()

本人学习 GOLANG 不久,这个用法不太明白
这行代码想要解决什么问题了?

上面有人写的这段代码,我到能看懂
<br>_fun,ok:=b.(interface{ Fun() })<br>if !ok{<br>return fmt.ErrorF("")<br>}<br><a target="_blank" href="http://_fun.Fun" rel="nofollow noopener">_fun.Fun</a>()<br>
这个是在判断,b 是否实现了含有 fun()的一个接口

在Golang(Go语言)的世界里,接口和面向对象编程(OOP)是构建灵活和可扩展软件架构的重要基石。虽然Go语言没有传统意义上的类和继承机制,但它通过接口和结构体提供了实现OOP思想的一种独特方式。

接口在Go中扮演着至关重要的角色。它们定义了一组方法签名,而不实现这些方法。这允许不同的结构体只要实现了接口中的方法,就可以被视为该接口的一个实现。这种设计带来了极大的灵活性,因为你可以轻松地将一个结构体的实现替换为另一个,只要它们都实现了相同的接口。

关于面向对象,Go语言采用了组合优于继承的哲学。通过结构体嵌套和接口组合,Go实现了类似于OOP中的继承和多态,但避免了继承带来的复杂性和脆弱性。这种设计使得代码更加简洁、清晰,并且易于维护。

在遐想中,我们或许会对Go语言的这些特性产生一些疑问或思考,但正是这些特性使得Go语言在并发编程、系统编程和网络编程等领域中表现出色。Go语言的接口和面向对象设计哲学鼓励开发者编写更加模块化、可测试和可维护的代码。

总之,虽然Go语言的接口和面向对象实现方式与传统OOP语言有所不同,但它们提供了同样强大的功能和灵活性。通过深入理解和应用这些特性,我们可以构建出更加高效、可靠和可扩展的软件系统。

回到顶部