【问题标题】:How to define a struct globally and reuse it packages如何全局定义结构并重用它的包
【发布时间】:2015-11-05 17:08:16
【问题描述】:

我是 Go 新手,遇到了这个“设计”问题。

我有一个通过通道传递作业的主程序。每个作业最终都会在单独的“worker”包中定义的函数中结束。作业是结构。

现在我希望调用每个函数,通过“结果”通道将结果作为通用结构返回。但是包不知道我在 main 中的结构定义,所以我无法定义它。

package main

type resultEvent struct {
    name  string
    desc  string
}

然后在工作包中:

package worker

func Test() {
   result := &resultEvent{name: "test"}
}    

当然这个想法是最终将这个结果发送到一个通道,但即使这个简单的例子也行不通,因为工人不知道 resultEvent。 这样做的正确方法是什么?

更新:

需要注意的是会有很多worker包,做不同的事情。类似于“插件”(只是根本不可插入)。 我不想在每个 go-file 中定义一个冗余结构,然后必须维护可能超过 50 个非常不同的工作包。

我正在寻找构建此结构的正确方法,因此我可以为所有工作包重用一个结构。

【问题讨论】:

  • 反对票有什么解释吗?

标签: go


【解决方案1】:

基本上,任何存在于package main 中的东西都只能被该包引用。如果你想让它在多个包之间共享,把它放在worker包中并导出它(第一个字母大写),然后从main导入worker

【讨论】:

  • 谢谢。无法引用 main,我想这很重要 :).. 我被诱使认为结构将是全局的。
  • 没有什么是全球性的。一切都存在于一个包中。
【解决方案2】:

无论如何,您都必须导入包含您想要使用的类型的包。但是,这对您不起作用的原因是您的类型未导出。您需要将类型名称大写;

type ResultEvent struct {
    name  string
    desc  string
}

值得检查导出和未导出的含义,但基本上大写表示导出,类似于其他系统语言中的 public 说明符。小写表示未导出,更像internalprivate

正如评论和其他答案中指出的那样,您无法导入 main,因此我相信您也必须移动您的类型定义。

【讨论】:

  • 你不能导入 main
  • 导入一个“structs.go”文件是否有意义,包含我需要的所有全局结构?有点像 C 中的 .h 文件?
  • @thelogix 我会说这不是真正的惯用语。 Go 中的包是按功能组织的。我会根据它们的功能来组织你的类型,根据它启用的功能类型来命名包,并在需要的地方导入它。
  • @thelogix 根据您所说的,这些类型应该都在一个由 50 个不同的工作包导入的包上。我只是建议不要将其命名为“结构”,我也不会将其描述为“全局”,它只是随处导入。无论用 50 个工作包描述这些类型用途的最佳术语都是很好的包名称候选者。
  • 众所周知,我使用带有许多共享结构的 models 包。
【解决方案3】:

一种可能的方法是:

package workerlib

type ResultEvent struct {
  Name        string  // Export the struct fields, unless you have a
  Description string  // real good reason not to.
}

然后将其余的辅助实用程序函数粘贴到该包中。除非您提供合适的方法从事件中读取名称和描述,否则只需导出字段即可。如果您绝对需要使它们只能在定义它们的包中更改,您可以保持它们不导出,然后提供一个函数来创建 ResultEvent 以及读取名称和描述的方法。

【讨论】:

  • 啊。没有意识到我还需要导出字段。我认为这就是我正在寻找的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多