Проблема заключается в том, что вы каждый раз повторно анализируете исходный код, создавая новый экземпляр types.Package
и связанные с ним types.Scope
, что приводит к типам с именем , происходящим из разных объявлений ( ссылка ).
Встроенные типы, такие как int
и error
, для которых вы получили true
, являются базовыми типами, которые по-разному трактуются при сравнении ( ссылка ),Они также объявлены в области «вселенная», которая, я считаю, всегда одна и та же, независимо от того, сколько раз вы повторно анализируете Src
( ссылка ).
Исправитьваша проблема, вы должны проанализировать источник один раз, а затем поделиться полученным *types.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)))
}