【问题标题】:Why are these Go types not identical?为什么这些 Go 类型不相同?
【发布时间】:2020-12-29 12:34:06
【问题描述】:

在下面的示例中,根据types.Identical(),从GetTime() 返回的time 类型与time.Time 不同。为什么是这样?这两种类型在打印时都是time.Time

package main

import (
    "fmt"
    "go/ast"
    "go/importer"
    "go/parser"
    "go/token"
    "go/types"

    "golang.org/x/tools/go/packages"
)

const example = `package main

import "time"

func GetTime() time.Time {
    return time.Time{}
}

func main() {
}`

func GetTimeObject() types.Object {
    cfg := &packages.Config{
        Mode:       packages.LoadAllSyntax,
    }
    loadedPackages, err := packages.Load(cfg, "time")
    if err != nil {
        panic(err)
    }

    timePkg := loadedPackages[0]
    timeObject := timePkg.Types.Scope().Lookup("Time")
    return timeObject
}

func main() {
    fset := token.NewFileSet()

    f, err := parser.ParseFile(fset, "example.go", example, 0)
    if err != nil {
        panic(err)
    }

    conf := types.Config{Importer: importer.Default()}
    pkg, err := conf.Check("example", fset, []*ast.File{f}, nil)
    if err != nil {
        panic(err)
    }

    getTimeObj := pkg.Scope().Lookup("GetTime")
    if getTimeObj == nil {
        panic("not found")
    }

    switch t := getTimeObj.Type().(type) {
    case *types.Signature:
        results := t.Results()
        if results.Len() != 1 {
            panic("unexpected")
        }

        retObject := results.At(0)
        timeObject := GetTimeObject()

        fmt.Printf("time type: %v\n", timeObject.Type()) // time.Time
        fmt.Printf("return type: %v\n", retObject.Type()) // time.Time
        fmt.Printf("identical: %t\n", types.Identical(timeObject.Type(), retObject.Type())) // false
    default:
        panic("unexpected")
    }
}

【问题讨论】:

    标签: go types abstract-syntax-tree


    【解决方案1】:

    它们是不同的,将您的代码更改为打印详细类型信息使用%T%#v,您会有所不同:

            fmt.Printf("time type: %T %#v\n", timeObject, timeObject.Type())                    
            fmt.Printf("return type: %T %#v\n", retObject, retObject.Type())                    
    

    输出:

    time type: *types.TypeName &types.Named{info:0x2, obj:(*types.TypeName)(0xc0017e9a90), orig:(*types.Struct)(0xc001b22780), underlying:(*types.Struct)(0xc001b22780), methods:[]*types.Func{(*types.Func)(0xc0017e8a00), (*types.Func)(0xc0017e8a50), (*types.Func)(0xc0017e8aa0), (*types.Func)(0xc0017e9ae0), (*types.Func)(0xc0017e9b30), (*types.Func)(0xc0017e9b80), (*types.Func)(0xc0017e9bd0), (*types.Func)(0xc0017e9c20), (*types.Func)(0xc0017e9c70), (*types.Func)(0xc0017e9cc0), (*types.Func)(0xc0017e9d10), (*types.Func)(0xc0017e9d60), (*types.Func)(0xc0017e9db0), (*types.Func)(0xc0017e9e00), (*types.Func)(0xc0017e9f90), (*types.Func)(0xc00195c000), (*types.Func)(0xc00195c050), (*types.Func)(0xc00195c0a0), (*types.Func)(0xc00195c0f0), (*types.Func)(0xc00195c140), (*types.Func)(0xc00195c190), (*types.Func)(0xc00195c1e0), (*types.Func)(0xc00195c280), (*types.Func)(0xc00195c2d0), (*types.Func)(0xc00195c370), (*types.Func)(0xc00195c3c0), (*types.Func)(0xc00195c410), (*types.Func)(0xc00195c460), (*types.Func)(0xc00195c4b0), (*types.Func)(0xc00195c910), (*types.Func)(0xc00195c960), (*types.Func)(0xc00195ca50), (*types.Func)(0xc00195caa0), (*types.Func)(0xc00195cdc0), (*types.Func)(0xc00195ce10), (*types.Func)(0xc00195ce60), (*types.Func)(0xc00195ceb0), (*types.Func)(0xc00195cf00), (*types.Func)(0xc00195cf50), (*types.Func)(0xc00195cfa0), (*types.Func)(0xc00195cff0), (*types.Func)(0xc00195d040), (*types.Func)(0xc00195d090), (*types.Func)(0xc00195d0e0), (*types.Func)(0xc00195d130), (*types.Func)(0xc00195d180), (*types.Func)(0xc00195d1d0), (*types.Func)(0xc00195d220), (*types.Func)(0xc00195d3b0), (*types.Func)(0xc00195d400)}}
    return type: *types.Var &types.Named{info:0x0, obj:(*types.TypeName)(0xc00005ff90), orig:types.Type(nil), underlying:(*types.Struct)(0xc000063320), methods:[]*types.Func{(*types.Func)(0xc000172ff0), (*types.Func)(0xc000173130), (*types.Func)(0xc0001732c0), (*types.Func)(0xc0001733b0), (*types.Func)(0xc0001734a0), (*types.Func)(0xc000173590), (*types.Func)(0xc000173680), (*types.Func)(0xc000173770), (*types.Func)(0xc000173810), (*types.Func)(0xc000173900), (*types.Func)(0xc0001739f0), (*types.Func)(0xc000173b30), (*types.Func)(0xc000173c70), (*types.Func)(0xc000173db0), (*types.Func)(0xc000173ea0), (*types.Func)(0xc000173f90), (*types.Func)(0xc0003e0140), (*types.Func)(0xc0003e0460), (*types.Func)(0xc0003e0550), (*types.Func)(0xc0003e0640), (*types.Func)(0xc0003e0730), (*types.Func)(0xc0003e09b0), (*types.Func)(0xc0003e0af0), (*types.Func)(0xc0003e0c80), (*types.Func)(0xc0003e0d70), (*types.Func)(0xc0003e0e60), (*types.Func)(0xc0003e0f50), (*types.Func)(0xc0003e1040), (*types.Func)(0xc0003e1130), (*types.Func)(0xc0003e1270), (*types.Func)(0xc0003e13b0), (*types.Func)(0xc0003e1590), (*types.Func)(0xc0003e17c0), (*types.Func)(0xc0003e18b0), (*types.Func)(0xc0003e19a0), (*types.Func)(0xc0003e1ae0), (*types.Func)(0xc0003e1bd0), (*types.Func)(0xc0003e1d10), (*types.Func)(0xc0003e1e00), (*types.Func)(0xc0003e1ef0), (*types.Func)(0xc0003e4050), (*types.Func)(0xc0003e4190), (*types.Func)(0xc0003e42d0), (*types.Func)(0xc0003e4410), (*types.Func)(0xc0003e4550), (*types.Func)(0xc0003e4690), (*types.Func)(0xc0003e47d0), (*types.Func)(0xc0003e4910), (*types.Func)(0xc0003e4a50), (*types.Func)(0xc0003e4b90)}}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2015-02-15
      相关资源
      最近更新 更多