dtef9322
dtef9322
2018-10-16 07:37

包源之间的循环依赖关系

已采纳

Let's say you have a package mypack with two source files mypack/a.go and mypack/b.go. Both of those source files depend on each another but the Go compiler doesn't complain. If you split that package into two, apack/a.go and bpack/b.go, the Go compiler will say import cycle not allowed.

My understanding of how package dependencies are handled is that the compiler will construct a graph of the imports. The graph is analyzed and somehow (I would love to learn about the algorithm that does this!) the order of compilation calculated. The order cannot be calculated if there is a cycle in the graph so the compiler complains.

What I don't understand is how the Go compiler is able to resolve dependencies between sources of a package but not able to resolve dependencies between packages. If the two sources depend on each other then you have to do some crazy acrobatics and compile them both at the same time somehow.

Could someone clear this up for me?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • doumu6997 doumu6997 3年前

    [...] how the Go compiler is able to resolve dependencies between sources of a package but not able to resolve dependencies between packages. If the two sources depend on each other then you have to do some crazy acrobatics and compile them both at the same time somehow.

    The question is based on wrong assumptions on how Go code is structured and compiled: A source file does not have a dependency by definition. A package has dependencies (all imports from all its source files). Dependencies are packages (not source files). To compile a package all dependencies have to be available before compilation starts.

    You really must stop thinking in terms of source files. Source files have (almost) no meaning in how Go code is compiled. A package's source may consist of one or several source files and this is basically the only point where source files enter compiling Go code. Everything relevant revolves around packages and packages only: You compile packages, you import packages, etc.

    (Just for completeness: Build tags work on source level and package initialization can depend on source code organization and by manual invoking gc you can do more than through the go tool.)

    点赞 评论 复制链接分享
  • doudouwen2763 doudouwen2763 3年前

    A package is compiled as a single unit, regardless of how many source files are used. This shouldn't really be that mysterious.

    Further, your assertion that "The order cannot be calculated if there is a cycle" is simply wrong. It's trivial to calculate such things--many languages do this. Go prohibits this, though, as a matter of policy, because it leads to tight coupling of code, and code that is difficult to understand, not because it's impossible.

    点赞 评论 复制链接分享

相关推荐