gpt4 book ai didi

go/types.Identical 不能比较其他包中的两个相同类型?

转载 作者:IT王子 更新时间:2023-10-29 02:20:15 26 4
gpt4 key购买 nike

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

import (
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
)

const (
Src = `
package types

import (
"io"
"net/http"
)

var (
IOReader io.Reader
Err error
StatusCode int
Request *http.Request
Response *http.Response
)
`
)

const (
TypeIOReader = "IOReader"
TypeErr = "Err"
TypeStatusCode = "StatusCode"
TypeRequest = "Request"
TypeResponse = "Response"
)


func GetType(name string) types.Type {
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "types.go", Src, 0)
if err != nil {
log.Fatal(err)
}

conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("impler/types", fset, []*ast.File{file}, nil)
return pkg.Scope().Lookup(name).Type()
}

GetType(name string) types.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

types.Identical 似乎无法比较其他包中的两个相同类型?我如何比较它们?

types.TypeString(typ1, nil) == types.TypeString(typ2, nil) 是否足够健壮?

最佳答案

问题是您每次都在重新解析源代码,创建 types.Package 及其关联的 types.Scope 的新实例,这会导致已命名 类型源自不同的声明 ( link )。

interror 这样你得到 true 的内置类型是基本类型,在比较中被区别对待 ( link ) .它们也在“universe”范围内声明,我相信,无论您重新解析 Src 多少次(link),它总是相同的。

要解决您的问题,您必须解析一次源代码,然后共享生成的 *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)))
}

关于go/types.Identical 不能比较其他包中的两个相同类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52790293/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com