当 init() 函数之间存在依赖关系时,如何将包拆分为多个文件?
How do I split a package into multiple files when there are dependencies between their init() functions?
我有一个包的go文件越来越笨重,所以我想把它拆分成多个逻辑文件。
我的文件目前拆分(和删节)如下:
// 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
},
})
}
然后我使用 main.go
中的包:
result := graphql.Do(graphql.Params{
Schema: schema.Schema,
RequestString: r.URL.Query()["query"][0],
})
虽然包构建正确,但当我 运行 它时它会报错:
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
这是因为:
node.go depends on testtype.go
testtype.go depends on node.go
root.go depends on node.go and testtype.go
go build
通过按字母顺序对文件名排序来构建页面中的文件:node.go
然后 root.go
然后 testtype.go
.
如果我将 root.go
重命名为 z.go
,它会正确构建和 运行。除了将 root.go
重命名为 z.go
这不太理想之外,还有其他方法可以使它以可扩展的方式工作吗?
您可以只使用一个 init()
函数并将所有内容放入其中。
或者,如果您想在多个 .go
文件中坚持使用多个 init()
函数,则创建一个 "master" 将调用 init()
的初始化函数,然后重命名其他初始化函数,例如initA()
、initB()
,并按正确顺序从 master init 中调用它们:
func init() {
initA()
initB()
}
查看相关问题+答案:
我有一个包的go文件越来越笨重,所以我想把它拆分成多个逻辑文件。
我的文件目前拆分(和删节)如下:
// 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
},
})
}
然后我使用 main.go
中的包:
result := graphql.Do(graphql.Params{
Schema: schema.Schema,
RequestString: r.URL.Query()["query"][0],
})
虽然包构建正确,但当我 运行 它时它会报错:
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
这是因为:
node.go depends on testtype.go
testtype.go depends on node.go
root.go depends on node.go and testtype.go
go build
通过按字母顺序对文件名排序来构建页面中的文件:node.go
然后 root.go
然后 testtype.go
.
如果我将 root.go
重命名为 z.go
,它会正确构建和 运行。除了将 root.go
重命名为 z.go
这不太理想之外,还有其他方法可以使它以可扩展的方式工作吗?
您可以只使用一个 init()
函数并将所有内容放入其中。
或者,如果您想在多个 .go
文件中坚持使用多个 init()
函数,则创建一个 "master" 将调用 init()
的初始化函数,然后重命名其他初始化函数,例如initA()
、initB()
,并按正确顺序从 master init 中调用它们:
func init() {
initA()
initB()
}
查看相关问题+答案: