go/types.idential无法比较其他包中的两个相同类型?
我编写了一些代码,通过“go/types”获得特殊类型 函数go/types.idential无法比较其他包中的两个相同类型?,go,Go,我编写了一些代码,通过“go/types”获得特殊类型 函数GetType(name string)类型。Type可以使其生效 当我比较两种类型时,我得到了一些奇怪的结果 log.Println(types.Identical(GetType(TypeResponse), GetType(TypeResponse))) log.Println(types.Identical(GetType(TypeIOReader), GetType(TypeIOReader))) log.Println(ty
GetType(name string)类型。Type
可以使其生效
当我比较两种类型时,我得到了一些奇怪的结果
log.Println(types.Identical(GetType(TypeResponse), GetType(TypeResponse)))
log.Println(types.Identical(GetType(TypeIOReader), GetType(TypeIOReader)))
log.Println(types.Identical(GetType(TypeStatusCode), GetType(TypeStatusCode)))
log.Println(types.Identical(GetType(TypeErr), GetType(TypeErr)))
结果是
false
false
true
true
似乎是类型。相同的无法比较其他包中的两个相同类型?
我如何比较它们
类型。类型字符串(typ1,nil)=类型。类型字符串(typ2,nil)
足够健壮吗?Go中具有不同名称的类型被视为不同的类型,即使它们具有相同的结构。以下是有关golang类型规则的更多信息:
如果要比较它们,可以将一个值转换为另一种类型:
type A {...} // some declaration
type B {...} // the same declaration
if a == A(b) {...}
问题在于,您每次都在解析源代码,创建types.Package
及其关联的types.Scope
的新实例,这导致命名类型源自不同的声明()
内置类型,如int
和error
,您得到的true
是基本类型,比较()会对它们进行不同的处理。它们也在“universe”范围内声明,我相信,无论您重新解析Src
()多少次,它都是相同的
要解决问题,您必须解析源代码一次,然后共享生成的*类型。Package
package main
import (
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
)
const Src = `
package types
import (
"io"
"net/http"
)
var (
IOReader io.Reader
Response *http.Response
)
`
const (
TypeIOReader = "IOReader"
TypeResponse = "Response"
)
func GetType(name string, pkg *types.Package) types.Type {
return pkg.Scope().Lookup(name).Type()
}
func main() {
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "types.go", Src, 0)
if err != nil {
panic(err)
}
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("impler/types", fset, []*ast.File{file}, nil)
if err != nil {
panic(err)
}
log.Println(types.Identical(GetType(TypeResponse, pkg), GetType(TypeResponse, pkg)))
log.Println(types.Identical(GetType(TypeIOReader, pkg), GetType(TypeIOReader, pkg)))
}
您是否检查了conf.check返回的错误?OP用于比较的两个实例。OP的比较失败的是导入的类型、相同的名称、相同的包,但导入的是本地包,而不是本地包。与一件事无关!=B.与p.A.有关!=通讯社
package main
import (
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
)
const Src = `
package types
import (
"io"
"net/http"
)
var (
IOReader io.Reader
Response *http.Response
)
`
const (
TypeIOReader = "IOReader"
TypeResponse = "Response"
)
func GetType(name string, pkg *types.Package) types.Type {
return pkg.Scope().Lookup(name).Type()
}
func main() {
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "types.go", Src, 0)
if err != nil {
panic(err)
}
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("impler/types", fset, []*ast.File{file}, nil)
if err != nil {
panic(err)
}
log.Println(types.Identical(GetType(TypeResponse, pkg), GetType(TypeResponse, pkg)))
log.Println(types.Identical(GetType(TypeIOReader, pkg), GetType(TypeIOReader, pkg)))
}