英文:
Why is this `*invalid type` instead of `*Games`?
问题
如果你在这里运行分析包:https://github.com/frederikhors/iss-goland-invalid-type,使用以下命令:
go run ./analysis
它会打印出:
field.Name: id - field.Type: string
field.Name: name - field.Type: string
field.Name: games - field.Type: *invalid type
我不明白的是为什么我得到的是 *invalid type
而不是 *Games
?
代码部分:
- analyis/main.go:
package main
import (
"go/types";
"golang.org/x/tools/go/packages"
)
func main() {
playerModel := LoadPackage("./player.go")
var playerStruct *types.Struct
for _, entity := range playerModel.Types.Scope().Names() {
if entity == "Player" {
playerStruct = GetStruct(entity, playerModel)
break
}
}
for i := 0; i < playerStruct.NumFields(); i++ {
field := playerStruct.Field(i)
println("field.Name: " + field.Name() + " - field.Type: " + field.Type().String())
}
}
func LoadPackage(path string) *packages.Package {
const mode = packages.NeedTypes |
packages.NeedName |
packages.NeedSyntax |
packages.NeedFiles |
packages.NeedTypesInfo |
packages.NeedTypesInfo |
packages.NeedModule
cfg := &packages.Config{Mode: mode}
pkgs, err := packages.Load(cfg, path)
if err != nil {
panic(err)
}
return pkgs[0]
}
func GetStruct(structName string, pkg *packages.Package) *types.Struct {
foundStruct := pkg.Types.Scope().Lookup(structName)
if foundStruct == nil {
return nil
}
res, _ := foundStruct.Type().Underlying().(*types.Struct)
return res
}
- player.go:
type Player struct {
id string
name string
games *Games
}
- games.go:
package main
type Games struct {
wins []string
losses []string
}
英文:
If you run the analysis package here: https://github.com/frederikhors/iss-goland-invalid-type with:
go run ./analysis
it will print:
field.Name: id - field.Type: string
field.Name: name - field.Type: string
field.Name: games - field.Type: *invalid type
What I don't understand is why I'm having *invalid type
instead of *Games
?
Code
- analyis/main.go:
package main
import (
"go/types"
"golang.org/x/tools/go/packages"
)
func main() {
playerModel := LoadPackage("./player.go")
var playerStruct *types.Struct
for _, entity := range playerModel.Types.Scope().Names() {
if entity == "Player" {
playerStruct = GetStruct(entity, playerModel)
break
}
}
for i := 0; i < playerStruct.NumFields(); i++ {
field := playerStruct.Field(i)
println("field.Name: " + field.Name() + " - field.Type: " + field.Type().String())
}
}
func LoadPackage(path string) *packages.Package {
const mode = packages.NeedTypes |
packages.NeedName |
packages.NeedSyntax |
packages.NeedFiles |
packages.NeedTypesInfo |
packages.NeedTypesInfo |
packages.NeedModule
cfg := &packages.Config{Mode: mode}
pkgs, err := packages.Load(cfg, path)
if err != nil {
panic(err)
}
return pkgs[0]
}
func GetStruct(structName string, pkg *packages.Package) *types.Struct {
foundStruct := pkg.Types.Scope().Lookup(structName)
if foundStruct == nil {
return nil
}
res, _ := foundStruct.Type().Underlying().(*types.Struct)
return res
}
- player.go:
type Player struct {
id string
name string
games *Games
}
- games.go:
package main
type Games struct {
wins []string
losses []string
}
答案1
得分: 3
你明确地只加载了一个文件,使用LoadPackage("./player.go")
。而这个文件并不是声明Games
类型的文件。要加载整个包中所有类型的信息,你需要加载整个包。
你需要使用LoadPackage(".")
。
英文:
You are explicitly loading only a single file with LoadPackage("./player.go")
. And that file is not the one in which the Games
type is declared. To load information on all types of a package you need to load the whole package.
You need to use LoadPackage(".")
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论