go/types: differentiate b/w defined named types

64 kali dilihat
Langsung ke pesan pertama yang belum dibaca

Sebastien Binet

belum dibaca,
21 Sep 2021, 09.47.2021/09/21
kepadagolang-nuts
hi there,

I am a bit confused by go/types and defined named types:

https://play.golang.org/p/izESp473jOq

the above link shows a program using the go/types package and shows how
the four types T0, T1, T2 and T3:

```
package p

type T0 struct { F int}
type T1 struct { T0 }
type T2 T1
type T3 T0
```

map to types defined in go/types:

T0: type p.T0 struct{F int} -- obj=*types.TypeName typ=*types.Named -- under=*types.Struct
T1: type p.T1 struct{p.T0} -- obj=*types.TypeName typ=*types.Named -- under=*types.Struct
T2: type p.T2 struct{p.T0} -- obj=*types.TypeName typ=*types.Named -- under=*types.Struct
T3: type p.T3 struct{F int} -- obj=*types.TypeName typ=*types.Named -- under=*types.Struct

how would I use go/types to differentiate between T1 and T2?
they are 2 named types whose underlying types are (eventually):
'struct { T0 }'

but, from the doc string of Type.Underlying:
```
// Underlying returns the underlying type of a type
// w/o following forwarding chains. Only used by
// client packages (here for backward-compatibility).
```

I was actually expecting to get:
- *types.Struct for t1.Underlying()
- *types.Named for t2.Underlying()

so: how could I differentiate between a named type that's defined from
another named type and one that's defined (directly) from a struct ?


Axel Wagner

belum dibaca,
21 Sep 2021, 09.57.2521/09/21
kepadaSebastien Binet, golang-nuts
The underlying type is defined recursively:

Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its type declaration.

 (emphasis mine). From a type-system perspective, there is no real difference between these two types. The Go type system treats them the same.

So, if you need to differentiate between them, you have to go back from the types-level to the AST level. That's unfortunately a bit difficult, AFAIK. I think you have to use the `token.Pos` of the `*TypeName` and then traverse the `ast.File`s of the package until you find that position. That should give you an `ast.TypeSpec`, which can tell you if its `Type` field is an identifier, or a type literal. Not super ergonomic, but AFAIK the only way.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CEFLY6WPOVY6.1VEGTAPD57RSO%40clrinfopc42.

Sebastien Binet

belum dibaca,
21 Sep 2021, 10.14.0921/09/21
kepadaAxel Wagner, golang-nuts
Axel,

On Tue Sep 21, 2021 at 15:56 CET, Axel Wagner wrote:
> The underlying type is defined recursively
> <https://golang.org/ref/spec#Types>:
>
> Each type T has an underlying type: If T is one of the predeclared
> boolean,
> > numeric, or string types, or a type literal, the corresponding underlying
> > type is T itself. Otherwise, T's underlying type is *the underlying type
> > of the type* to which T refers in its type declaration.
>
>
> (emphasis mine). From a type-system perspective, there is no real
> difference between these two types. The Go type system treats them the
> same.
>
> So, if you need to differentiate between them, you have to go back from
> the
> types-level to the AST level. That's unfortunately a bit difficult,
> AFAIK.
> I think you have to use the `token.Pos` of the `*TypeName` and then
> traverse the `ast.File`s of the package until you find that position.
> That
> should give you an `ast.TypeSpec`, which can tell you if its `Type`
> field
> is an identifier, or a type literal. Not super ergonomic, but AFAIK the
> only way.

ok, thanks for the quick answer.

cheers,
-s
Balas ke semua
Balas ke penulis
Teruskan
0 pesan baru