dsfsad089111 2016-01-28 05:03
浏览 48
已采纳

当init()函数之间存在依赖关系时,如何将程序包拆分为多个文件?

I have a go file for a package that is becoming unwieldy, so I want to split it into multiple logical files.

I have the files currently split (and abridged) like so:

// node.go
package schema

import (
    "github.com/graphql-go/graphql"
    "github.com/graphql-go/relay"
)

var nodeDefinitions *relay.NodeDefinitions

func init() {
    nodeDefinitions = relay.NewNodeDefinitions(relay.NodeDefinitionsConfig{
        IDFetcher: func(id string, info graphql.ResolveInfo) interface{} {
            ...
        },
        TypeResolve: func(value interface{}, info graphql.ResolveInfo) *graphql.Object {
            // based on the type of the value, return GraphQLObjectType
            switch value.(type) {
            default:
                return testType //Depends on the test.go
            }
        },
    })
}


//root.go
package schema

import (
    "github.com/graphql-go/graphql"
)

var Schema graphql.Schema

func init() {
    queryType := graphql.NewObject(graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
            "version": &graphql.Field{
                 Type: versionType, //Depends on testtype.go
                 ...
            },
            "node": nodeDefinitions.NodeField, //Depends on node.go
        },
    })

    Schema, _ = graphql.NewSchema(graphql.SchemaConfig{
        Query: queryType,
    })
}

//testtype.go
package schema

import (
    "github.com/graphql-go/graphql"
    "github.com/graphql-go/relay"
)

var testType *graphql.Object

func init() {
    testType = graphql.NewObject(graphql.ObjectConfig{
        ...
        Interfaces: []*graphql.Interface{
            nodeDefinitions.NodeInterface, //Depends on node.go
        },
    })
}

I then use the package in main.go:

result := graphql.Do(graphql.Params{
        Schema:        schema.Schema,
        RequestString: r.URL.Query()["query"][0],
    })

While the package builds correctly, it complains with an error when I run it:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x48e4b6]

goroutine 1 [running]:
test/testproject/vendor/github.com/graphql-go/graphql.(*Object).Error(0x0, 0xc082003380, 0x3c)
        C:/go/src/test/testproject/vendor/github.com/graphql-go/graphql/definition.go:440 +0x26
test/testproject/vendor/github.com/graphql-go/graphql.defineFieldMap(0xda48b0, 0xc08206c780, 0xc0820550e0, 0xda
        C:/go/src/test/testproject/vendor/github.com/graphql-go/graphql/definition.go:498 +0x532
test/testproject/vendor/github.com/graphql-go/graphql.(*Object).Fields(0xc08206c780, 0xc08206c780)
        C:/go/src/test/testproject/vendor/github.com/graphql-go/graphql/definition.go:416 +0x106
test/testproject/vendor/github.com/graphql-go/graphql.typeMapReducer(0xc082055110, 0xda4560, 0xc08206c780, 0x0,
        C:/go/src/test/testproject/vendor/github.com/graphql-go/graphql/schema.go:208 +0x79a
test/testproject/vendor/github.com/graphql-go/graphql.NewSchema(0xc08206c780, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
        C:/go/src/test/testproject/vendor/github.com/graphql-go/graphql/schema.go:67 +0x809
test/testproject/schema.init.2()
        C:/go/src/test/testproject/schema/root.go:37 +0x244
test/testproject/schema.init()
        C:/go/src/test/testproject/schema/version.go:37 +0x5b
main.init()
        C:/go/src/test/testproject/main.go:37 +0x42

This is because:

node.go depends on testtype.go
testtype.go depends on node.go
root.go depends on node.go and testtype.go

go build builds the files in the page by sorting the filenames alphabetically: node.go then root.go then testtype.go.

If I rename root.go to z.go, it builds and runs correctly. Besides renaming root.go to z.go which is less than ideal, is there any other way I can get this working in a scalable way?

  • 写回答

1条回答 默认 最新

  • dtjo87679 2016-01-28 05:27
    关注

    You could use just one init() function and put everything in that.

    Or if you want to stick with multiple init() functions in multiple .go files, then create one "master" init function that will be called init(), and rename other init functions, e.g. initA(), initB(), and call these from the master init in proper order:

    func init() {
        initA()
        initB()
    }
    

    See related question+answer: What does lexical file name order mean?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 来真人,不要ai!matlab有关常微分方程的问题求解决,
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算