如何在全局范围内定义一个结构体并在不同的包中重用它?

huangapple go评论81阅读模式
英文:

How to define a struct globally and reuse it packages

问题

我对Go语言非常陌生,有一个“设计”问题。

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

现在,我希望每个被调用的函数都通过一个“result”通道返回结果作为一个公共结构体。但是包不知道我在主程序中定义的结构体定义,所以我无法定义它。

在主程序中定义如下:

package main

type resultEvent struct {
    name string
    desc string
}

然后在一个worker包中:

package worker

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

当然,想法是最终将这个结果发送到一个通道中,但是即使这个简单的例子也行不通,因为worker不知道resultEvent。

正确的做法是什么?

更新:

值得注意的是,将会有许多worker包,执行不同的任务。有点像“插件”(只是根本不可插拔)。
我不想在每个go文件中定义一个冗余的结构体,然后不得不在可能有50个非常不同的worker包中维护它。

我想知道如何正确地组织这个结构,以便我可以在所有worker包中重用一个结构体。

英文:

Im very new to Go and have this "design" problem.

I have a main program passing jobs through channels. Each job will end up in a function defined in separate "worker" packages. Jobs are structs.

Now i want each function called, to return result as a common struct through a "result" channel. But the package doesnt know about the struct definition i have in main and so i cannot define it.

package main

type resultEvent struct {
	name  string
	desc  string
}

Then in a worker package:

package worker

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

Of course the idea is to eventually send this result down a channel, but even this simple example wont work, because worker doesnt know about resultEvent.
What would be the correct way of doing this?

Update:

It should be noted that there will be many worker packages, doing different things. Sorta like "plugins" (only not pluggable at all).
I dont want to define a redundant struct in each go-file and then have to maintain that over maybe 50 very different worker-packages.

Im looking for what would be the correct way to structure this, so i can reuse one struct for all worker-packages.

答案1

得分: 4

基本上,任何位于package main中的内容只能从该包中引用。如果你希望它在多个包之间共享,将其放在worker包中并导出它(将首字母大写),然后从main中导入worker

英文:

Basically, anything that lives in package main will only ever be able to be referenced from that pacakge. If you want it to be shared between multiple packages, put it in the worker package and export it (Upper case the first letter), then import worker from main.

答案2

得分: 2

无论如何,您都需要导入包含您想使用的类型的包。然而,这不起作用的原因是因为您的类型没有被导出。您需要将类型的名称大写,例如:

type ResultEvent struct {
    name  string
    desc  string
}

值得注意的是,要了解导出和未导出的含义,但基本上大写表示导出,类似于其他系统语言中的“public”修饰符。小写表示未导出,更像是“internal”或“private”。

正如评论和其他答案中指出的,您不能导入main,所以我认为您还需要移动类型的定义。

英文:

No matter what, you will have to import the package which contains the type you'd like to use. However, the reason this isn't working for you is because your type is not exported. You need to uppercase the types name like;

type ResultEvent struct {
    name  string
    desc  string
}

Worth checking out what exported vs unexported means but basically upper case means exported which is similar to the public specifier in other systems languages. Lower case means unexported which is more like internal or private.

As pointed out in the comment and other answer you can't import main so I believe you'll have to move your types definition as well.

答案3

得分: 1

一种可能的方式是这样的:

package workerlib

type ResultEvent struct {
  Name        string  // 导出结构体字段,除非你有一个非常好的理由不这样做。
  Description string  // 导出结构体字段,除非你有一个非常好的理由不这样做。
}

然后将其余的工作器实用函数放在该包中除非你提供适当的方法从事件中读取名称和描述否则只需导出这些字段如果你绝对需要使它们只能在定义它们的包内部更改你可以将它们保持为未导出的然后提供一个函数来创建 ResultEvent以及读取名称和描述的方法
英文:

One possible way would be something like:

package workerlib

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

Then stick the rest of the worker utility functions in that package. Unless you provide suitable methods to read the name and description from an event, simply export the fields. If you have an absolute need to make them changeable only from within the package they're defined in, you could keep them unexported, then provide a function to create a ResultEvent as well as methods to read the name and description.

huangapple
  • 本文由 发表于 2015年11月5日 06:00:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/33532892.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定