通过Golang的结构进行循环导入 [英] Circular import with structs in Golang

查看:360
本文介绍了通过Golang的结构进行循环导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Golang有几个模块的项目。由于下面的情况,我遇到了循环导入的问题:

详细信息



模块游戏包含一个结构与当前的游戏状态。另一个模块(Modifier)正在做一些游戏特定的东西和计算,因此修改了游戏状态。因此,Modifier将需要struct Game,但不需要Game中的任何方法。



问题:




    <
  • 修饰符需要Game结构




在我看来,这是一种常见的情况,所以我想知道如何以最好的方式解决问题。我的解决方案是创建第三个模块Structs,它只包含整个应用程序的所有结构。这是一个很好的解决方案吗?

解决方案

使用第三个包选项:

  yourgame / 
state /
state.go
修饰符/
modifier.go
main.go

main.go 会将两个组件粘合在一起:

 导入yourgame / state
导入yourgame / modifier

类型游戏结构{
state state.State
modifier modifier.Modifier
}

func main(){
//类似于:
var game Game
game.modifier.Modify(game.state)
}

这种方法虽然可能过于紧密。而不是操纵一个基本上全局的状态对象,我会试着将数据分割成你需要的修饰符。



抽象中的推理很难,所以这里是我的意思是一个具体的例子。在你的游戏中:

 类型Object结构{
ID,X,Y int
//更多数据这里

类型游戏struct {
对象map [int] * Object
}

在你的修改器中,假设我们有一个移动对象的AI模块。如果他所关心的是一个对象的位置,您可以创建一个接口:

  //在您的游戏/修饰符中
类型对象接口{
GetCoordinates()(int,int)
SetCoordinates(int,int)

类型修饰符struct {}
func(m *修饰符)更新(obj对象){}

然后我们只需将这些方法添加到我们的原始对象:

  type(obj * Object)GetCoordinates()(int,int){
return obj.X,obj .y
}
type(obj * Object)SetCoordinates(x,y int){
obj.X,obj.Y = x,y
}

现在您可以传递对象到您的修饰符而不需要循环依赖。



现在,如果事实证明你的修饰符界面最终看起来几乎与你的游戏对象相同,那么第三个结构包可能是合理的,所以你并不总是在重复自己。例如,考虑 net / url

I have a project with several modules in Golang. I am having problem with circular imports because of the scenario below:

Details

A module Game contains a struct with the current Game state. Another module (Modifier) is doing some game specific stuff and calculations and therefore modifies the game state. Because of this, Modifier will need the struct Game, but not any methods from Game. Modifier is called from Game and here we have the circular import.

Problem:

  • Game initiates Modifier

  • Modifier needs Game struct

It seems to me that this is a common scenario, so I wonder how I should solve it in the best way. My solution would be to create a third module "Structs" which just contains all the structs for the whole application. Is this a good solution?

解决方案

With the 3rd package option:

yourgame/
  state/
    state.go
  modifier/
    modifier.go
  main.go

main.go would glue the two components together:

import "yourgame/state"
import "yourgame/modifier"

type Game struct {
    state    state.State
    modifier modifier.Modifier
}

func main() {
    // something like: 
    var game Game
    game.modifier.Modify(game.state)
}

This approach is probably too tightly coupled though. Rather than manipulating an essentially global state object, I would try to slice up the data into just what you need for the modifier.

Reasoning in the abstract is hard, so here's a concrete example of what I mean. In your game:

type Object struct {
    ID, X, Y int
    // more data here
}
type Game struct {
    Objects map[int]*Object
}

In your "modifier", let's suppose we had an AI module that moves an object. If all he cares about is the position of a single object you can create an interface:

// in yourgame/modifier
type Object interface {
    GetCoordinates() (int, int)
    SetCoordinates(int, int)
}
type Modifier struct {}
func (m *Modifier) Update(obj Object) { }

Then we just have to add those methods to our original Object:

type (obj *Object) GetCoordinates() (int, int) {
    return obj.X, obj.Y
}
type (obj *Object) SetCoordinates(x, y int) {
    obj.X, obj.Y = x, y
}

And now you can pass objects to your modifier without needing a cyclic dependency.

Now if it turns out your "modifier" interface ends up looking almost exactly the same as your game object, then a 3rd package of structs is probably reasonable so you aren't always repeating yourself. For an example consider net/url.

这篇关于通过Golang的结构进行循环导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆