Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 周期性进口和缺乏仿制药导致头痛_Go - Fatal编程技术网

Go 周期性进口和缺乏仿制药导致头痛

Go 周期性进口和缺乏仿制药导致头痛,go,Go,假设我在golang有两个文件: // main/a/a.go import "main/b" type Model struct { ID int `json:"id"` Me int `json:"me"` You int `json:"you"` } func zoom(v b.Injection){ } func Start(){ // ... } 然后第二个文件看起来像: // mai

假设我在golang有两个文件:

// main/a/a.go
import "main/b"

type Model struct {
    ID         int    `json:"id"`
    Me         int    `json:"me"`
    You        int    `json:"you"`
}

func zoom(v b.Injection){

}

func Start(){
  // ...
}
然后第二个文件看起来像:

// main/b/b.go
import "main/a"

type Injection struct {
    ModelA a.Model
}


func GetInjection() Injection {
    return Injection{
        ModelA: a.Start(),
    }
}
a imports c
b imports a,c
如您所见,这些是循环导入,每个文件导入另一个文件。 所以我需要使用第三个文件,让这两个文件导入第三个文件

但我真的在为如何获得这一功能和避免循环导入而苦苦挣扎

我的第一步是将
注入
类型移动到第三个文件中:

   // main/c/c.go

    type Injection struct {
        ModelA interface{} // formerly a.Model
    }
现在看起来是这样的:

// main/b/b.go
import "main/a"

type Injection struct {
    ModelA a.Model
}


func GetInjection() Injection {
    return Injection{
        ModelA: a.Start(),
    }
}
a imports c
b imports a,c
因此没有更多的循环,但是问题是我不知道如何在
c.go
中为
a.Model
创建接口?出于正常原因,我上面使用的空
接口{}
不起作用


如何解决这两个原始文件的循环导入问题?

如果要将它们放入单独的包中,不能将
Model
zoom()
放在同一个包中,因为
zoom()
指的是
Injection
Injection
指的是
Model

因此,一个可能的解决方案是将
模型
放入包
a
zoom()
放入包
b
,并
注入包
c
c.Injection
可参考
a.Model
b.zoom()
可参考
c.Injection
。这里面没有圆圈:

   b.zoom() -------->   c.Injection ---------> a.Model
我假设在您的实际代码中还有其他引用,这些引用可能会阻止此操作,但您可以在包之间移动“东西”,或者将其分解为更多内容

同样,如果事情是“紧”的,那么你应该考虑把它们放在同一个包中,这样就没有问题要解决了。 解决循环导入问题的另一种方法是引入接口。例如,如果您的

zoom()
函数不会引用
Injection
,则包含
Model
zoom()
的包将不需要引用
Injection
的包

检查
zoom()。如果这是方法调用,那么已经很好了。如果没有,请将方法添加到
注入
。然后,您可以在
zoom()
的包中定义一个包含
zoom()
需要调用的方法的接口,并将其参数类型更改为此接口。在Go中实现接口是隐式的,没有意图声明。因此,您可以删除参数类型中的引用,但仍然可以将
Injection
值传递到
zoom()

此外,请检查:

我认为代码应该按照包提供的内容而不是包含的内容组织成包名。这有时是微妙的,但通常不是

例如,http提供http客户端和服务器

作为一个反例,包utils是一个糟糕的名称,是的,它提供了实用程序,但您不知道名称中的内容,实际上这个包是根据它包含的内容命名的

如果您的项目是一个库,它应该包含一个包(不包括示例和可能的实用程序命令),如果它包含更多的包,这表明库正在尝试做太多的事情

默认情况下,更倾向于避免多个包,只有在关注点明确分离的情况下,才按包分割代码。根据我的经验,复杂的、可能是循环的包结构的许多挫折都是由于项目中包太多造成的


有没有一个很好的理由首先将它们放在不同的包中?当使用单个软件包时,没有问题。@icza是的,不同的软件包,因为涉及到更多的文件,我只是尽可能地将其浓缩。啊,我想我必须把所有东西都放在同一个软件包中,在同一个文件夹中有20多个文件,哈哈,该死的名称空间,这太糟糕了,这不是你的错,戈兰fault@AlexanderMills我认为不允许循环导入是为了快速编译,但如果应用正确,可能会导致更干净/更符合逻辑的结构。它还可以帮助您更容易地理解包/模块的依赖关系。