问题标签 [go-interface]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
573 浏览

oop - 在没有语言支持类型层次结构的情况下对相关事物的层次结构进行建模

我是 Go 新手,我想做的第一件事就是将我的小标记页面生成库移植到 Go。主要的实现是在 Ruby 中,它的设计非常“经典的面向对象”(至少我从业余程序员的角度理解 OO)。它模拟了我如何看待标记文档类型之间的关系:

对于一个小项目,我可能会做这样的事情(翻译成我现在想要的 Go):

对于较大的项目,例如一个名为“Egg Sample”的网站,我将现有页面类型之一子类化,创建更深层次的层次结构:

这非常适合经典的面向对象设计:子类可以免费获得很多,它们只关注与父类不同的少数部分。例如,EggSamplePage 可以添加一些在所有 Egg Sample 页面中通用的菜单和页脚。

然而,Go 没有类型层次结构的概念:没有类,也没有类型继承。也没有动态的方法调度(在我看来,从上面可以看出;Go 类型HtmlPage不是“一种”Go 类型Page)。

Go 确实提供:

  • 嵌入
  • 接口

似乎这两个工具应该足以得到我想要的东西,但是在几次错误的开始之后,我感到很难过和沮丧。我的猜测是我想错了,我希望有人可以为我指出正确的方向,以了解如何做到这一点。

这是我遇到的一个具体的、真实的问题,因此,欢迎任何关于在不解决更广泛问题的情况下解决我的特定问题的建议。但我希望答案的形式是“通过以某种方式组合结构、嵌入和接口,您可以轻松获得所需的行为”,而不是回避它。我认为许多从经典 OO 语言过渡到 Go 的新手可能会经历类似的困惑时期。

通常我会在这里展示我损坏的代码,但我有几个版本,每个版本都有自己的问题,我不认为包括它们实际上会增加我的问题的清晰度,这个问题已经很长了。如果结果看起来有用,我当然会添加代码。

我做过的事情:

要更明确地说明我在寻找什么:

  • 我想学习惯用的 Go 方式来处理这样的层次结构。我更有效的尝试之一似乎最不像 Go:

    这让我很接近,但不是一直。我现在的观点是,学习 Go 程序员在这种情况下使用的习语似乎是一个失败的机会。

  • 我想尽可能地干(“不要重复自己”);text/template当每个模板的大部分内容与其他模板相同时,我不希望每种类型的页面都有单独的页面。我废弃的一个实现就是这样工作的,但是一旦我得到一个更复杂的页面类型层次结构,它似乎就会变得难以管理,如上所述。

  • 我希望能够拥有一个核心库包,它可以按原样用于它支持的类型(例如html5PagexhtmlPage),并且可以如上所述进行扩展,而无需直接复制和编辑库。(例如,在经典的 OO 中,我扩展/子类化 Html5Page 并进行一些调整。)我目前的尝试似乎不太适合这一点。

我希望正确的答案不需要太多代码来解释 Go 的思考方式。

更新:根据到目前为止的评论和答案,看来我离得不远了。我的问题一定比我想象的少一些面向设计的问题,而且更多的是关于我是如何做事的。所以这就是我正在使用的:

这可行,但它有几个问题:

  1. 感觉真的很尴尬
  2. 我在重复自己
  3. 这可能是不可能的,但理想情况下,我希望所有 Page 类型都有一个String()做正确事情的方法,而不是必须使用一个函数。

我强烈怀疑我做错了什么,并且有一些 Go 习语可以让这变得更好。

我想要一种做正确事情的String()方法,但是

page即使通过使用,也将始终使用这些方法HtmlPage,因为除了接口之外在任何地方都缺乏动态调度。

使用我当前的基于界面的页面生成,我不仅不能只做fmt.Println(p)p某种页面在哪里),而且我必须专门在 和 之间进行fmt.Println(dsts.PageString(p))选择fmt.Println(dsts.HtmlPageString(p))。这感觉很不对劲。

而且我在PageString()/HtmlPageString()之间和headerString()/之间笨拙地复制代码htmlHeaderString()

所以我觉得我仍然在遭受设计问题,因为在某种程度上仍然在思考 Ruby 或 Java 而不是 Go。我希望有一种直接且惯用的 Go 方法来构建一个库,该库具有我所描述的客户端界面。

0 投票
8 回答
131547 浏览

go - 类型转换接口切片

我很好奇为什么 Go 不会隐式转换为何[]T[]interface{}隐式转换Tinterface{}. 我错过了这种转换是否有一些重要的东西?

例子:

go build抱怨

不能在函数参数中使用 (type []string) 作为类型 []interface {}

如果我尝试明确地这样做,同样的事情:b := []interface{}(a)抱怨

无法将 (type []string) 转换为 type []interface {}

所以每次我需要进行这种转换(这似乎经常出现)时,我一直在做这样的事情:

有没有更好的方法来做到这一点,或者标准库函数来帮助这些转换?每次我想调用一个可以获取整数或字符串列表的函数时,多写 4 行代码似乎有点愚蠢。

0 投票
2 回答
190 浏览

interface - 了解界面

我是 Go 语言的新手,我试图通过编写一段简单的代码来理解 Go 接口。我收到一个错误,因为我无法理解引用接口方法的正确方法,请告诉我哪里出错了。

我是否通过 t.Noofchar() 正确引用了该方法?或者我还缺少其他东西

0 投票
1 回答
353 浏览

interface - Golang 接口来简化依赖?

嗯,我在处理接口时遇到了问题。

所以我使用 Go 包来处理我的 mongodb 东西,但我不想将该包导入到每个模型中,等等。我想将尽可能多的子包(如模型)保留在标准库中。所以我想我会像这样布置一些接口:

问题是,当我去使用这样的功能时:

通过传入我的 mgo.Database 在使用接口的包中找到:

我得到一个编译器错误:

controllers/handlers.go:35: 不能在函数参数中使用 ctx.Database (type *mgo.Database) 作为类型 dota.database: *mgo.Database 没有实现 dota.database (C 方法的错误类型) 有 C(string ) *mgo.Collection 想要 C(string) dota.collection

我对这个概念缺少什么?

0 投票
2 回答
7073 浏览

constructor - 接口中的构造方法?(在 Golang 中)

如果我有以下接口和结构:

那么如何将New()方法(作为构造函数)添加到接口中Shape

用例是,如果我有另一个结构Square

那么Square就会有一个方法Area()。但它不会有New()。我的目的是让任何继承的结构都自动Shape拥有一个New()方法。我怎样才能做到这一点?

0 投票
1 回答
2952 浏览

syntax - golang 对象工厂

我是golang的新手。我需要设计一个函数来根据输入创建不同类型的对象。但是我没有弄清楚如何设计界面。这是我的代码:

无论我要求 ObjectFactory 返回 *AA 还是 interface{},编译器都会告诉我错误。我怎样才能让它工作?

0 投票
1 回答
136 浏览

reflection - 设置作为 interface{} 传递的任何结构的变量

我想知道在使用interface{}值时如何使用反射设置变量,并且所有类型的结构都可以传递给func F(o interface{}). 如何将第一个值 (sA) 更改为“你好”?

0 投票
1 回答
54 浏览

go - 从接口获取指向结构的指针?

给定一个接口,我如何获得一个指向底层值的指针?

我天真的尝试是使用这样的类型断言:

但我得到:

0 投票
2 回答
80 浏览

go - 来自接口值的底层指针类型

如何从接口获取底层指针类型?

0 投票
2 回答
81 浏览

go - 我可以一般地为 Go-Lang 结构指定一个方法吗?

我一直在阅读go-lang 界面文档;但是我仍然不清楚是否有可能实现我想要的

这将正常工作;但是我更喜欢一些惯用的方法来将通用方法应用于两种类型并且只定义一次。就像是: