Go如何通过“隐式”界面提高生产率,与C#的扩展方法概念相比又如何?


21

在Go语言教程中,他们解释了界面如何工作:

Go没有课程。但是,您可以在结构类型上定义方法。该方法接收器出现在FUNC关键字和方法名之间自身的参数列表。

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

接口类型由一组方法定义。接口类型的值可以包含实现那些方法的任何值。

这是在Go中创建界面的唯一方法。Google进一步说明:

类型通过实现方法来实现接口。没有明确的意图interface声明(即声明)。

隐式接口将实现程序包与定义接口的程序包分离:两者都不依赖彼此。

它还鼓励定义精确的接口,因为您不必查找每个实现并使用新的接口名称对其进行标记。

所有这些听起来都像C#中的扩展方法,但是Go中的方法是残酷的多态的。它们将在实现它们的任何类型上运行。

Google声称这鼓励快速发展,但是为什么呢?您是否放弃了C#中的显式接口而放弃了某些东西?C#中的扩展方法能否允许人们从Go接口中获得C#的某些好处?



1
这些Go接口听起来比C#扩展方法更像C ++模板可以做什么。在C#中,没有什么比“实现方法A和B的任何类型”更重要的了,但是您可以使用C ++模板来实现。
2013年


“隐式接口”不只是鸭子输入的一种形式吗?
2013年

“'隐式接口'不只是鸭子输入的一种形式吗?” Go的接口是结构化类型的一个示例。非常相似的概念。
mortdeus

Answers:


12

我完全看不到扩展方法和隐式接口。

首先让我们说说目的。

扩展方法作为一种语法糖存在,专门用于使您能够像使用某个对象一样使用该方法,而无需访问该对象的内部。没有扩展方法,您可以做完全相同的事情,只是没有得到令人愉快的语法someObjectYouCantChange.YourMethod()而不得不调用YourMethod(someObjectYouCantChange)

但是,隐式接口的目的是使您可以在无权访问更改的对象上实现接口。这使您能够在您自己编写的任何对象与您无权访问其内部的任何对象之间创建多态关系。

现在让我们谈谈后果。

扩展方法实际上没有任何扩展名,这完全符合无情的安全约束。NET尝试使用该方法来辅助模型的不同视角(内部,外部,继承者和邻居的视角)。结果只是一些语法上的愉悦。

隐式接口的后果是几件事。

  • 偶然的接口实现,这可能是很不幸的事故,也可能是偶然的LSP违规,因为您遇到了别人不想要的接口而又不遵守合同的意图。
  • 通过简单地镜像对象接口(或什至只是创建一个满足该方法要求的接口),就可以轻松地使任何方法完全接受任何给定对象的模拟。
  • 可以轻松地创建适配器或其他各种类似模式的功能,以解决您无法插入内部的对象的问题。
  • 延迟接口实现,并在以后实现它而不必触及实际实现,仅在您确实要创建另一个实现者时才实现它。

Linq中扩展方法的实用性很大程度上源自它们将方法实现移植到接口上的能力尤其是IEnumerableand IQueryable。尽管您可以static使用实用程序类中的方法来伪造此代码,但这会很笨拙。
罗伯特·哈维

@RobertHarvey声称它将方法放到接口上并不一定正确,请注意接口上的实际方法与扩展方法之间的区别:接口上的方法将在实现该接口的类内部实现,因此比任何扩展方法都拥有更多的访问权限。再次改变视角,与外部相比,在类内部实现的代码具有特殊的视角。
吉米·霍法
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.