go/types.idential无法比较其他包中的两个相同类型?

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

我编写了一些代码,通过“go/types”获得特殊类型

函数
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)))
}