Underlying type constraints and pointers

125 views
Skip to first unread message

Aaron Beitch

unread,
Oct 21, 2022, 7:40:39 PM10/21/22
to golang-nuts
Hello,

I would like to provide some helper functions that work on pointer types and having trouble getting it to work with ~ type constraints.

Here is the problem in code: https://go.dev/play/p/z0sKEsUaL_d

I have types Foo and Bar. Bar's underlying type is Foo. I want a function that takes in pointers to types whose underlying type is Foo, but I get a compile error when trying to call this function:

    *Bar does not implement ~*Foo (*Bar missing in ~*main.Foo)

Should this work?

My real use case is around a hash map library. It's implementation is a copy of Go's built-in map, but allows the user to control the equal and hash function, thus allowing keys of any type rather than just comparable types. github.com/aristanetworks/gomap

I would like to provide helper functions for gomap.Map similar to those provided by golang.org/x/exp/maps and for those helpers to work on pointers to types whose underlying type is gomap.Map.

Thanks,
Aaron


Axel Wagner

unread,
Oct 22, 2022, 1:12:28 AM10/22/22
to Aaron Beitch, golang-nuts
On Sat, Oct 22, 2022 at 1:40 AM 'Aaron Beitch' via golang-nuts <golan...@googlegroups.com> wrote:
I have types Foo and Bar. Bar's underlying type is Foo.

The underlying type is defined recursively and always either a predeclared type (int, string…), or a type literal.
The underlying type of Bar is the underlying type of Foo, which is struct { data []string }. You might try using `~struct{ data []string }`.
 
I want a function that takes in pointers to types whose underlying type is Foo, but I get a compile error when trying to call this function:

    *Bar does not implement ~*Foo (*Bar missing in ~*main.Foo)

Should this work?

My real use case is around a hash map library. It's implementation is a copy of Go's built-in map, but allows the user to control the equal and hash function, thus allowing keys of any type rather than just comparable types. github.com/aristanetworks/gomap

I would like to provide helper functions for gomap.Map similar to those provided by golang.org/x/exp/maps and for those helpers to work on pointers to types whose underlying type is gomap.Map.

Thanks,
Aaron


--
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/d6c4621a-13d8-4cd2-b777-eef7a200cca2n%40googlegroups.com.

Axel Wagner

unread,
Oct 22, 2022, 1:13:25 AM10/22/22
to Aaron Beitch, golang-nuts
(or, for convenience, you can use a type alias `type foo = struct{ data []string }`, which should allow you to write ~foo.

Axel Wagner

unread,
Oct 22, 2022, 1:36:53 AM10/22/22
to Aaron Beitch, golang-nuts
Sorry, I literally just fell out of bed, so I jumped on the first thing I saw, which probably isn't the most helpful answer.
You might be interested in this sentence from the Go 1.18 release notes:

The Go compiler does not support accessing a struct field x.f where x is of type parameter type even if all types in the type parameter's type set have a field f. We may remove this restriction in a future release.
 
So while what I said is correct - the underlying type of Bar *isnt* Foo - I think the more disappointing fact is that what you want to do just won't work for now. It might in the future, but not right now.

Axel Wagner

unread,
Oct 22, 2022, 1:44:57 AM10/22/22
to Aaron Beitch, golang-nuts
Actually (maybe I should stop, think, and then E-Mail) this works: https://go.dev/play/p/SBDglnj8mQx
I'm not sure if the selector X(*a).data will actually copy the value, but I don't *think* it does.
I also tried this first: https://go.dev/play/p/3qUhyOkvcVm
The fact that this doesn't work looks like a bug to me, to be honest.

Aaron Beitch

unread,
Nov 1, 2022, 8:42:08 PM11/1/22
to golang-nuts
Thanks for your help here! You helped me realize the thing I really want access to is the methods of Foo and Bar, and not the struct fields (my example was misleading).

What I would really like to have is a constraint that the type must have an underlying type of Foo, but that isn't working how I want. So, what I can do instead is define an interface that includes the methods that Foo provides and use that as my constraint. https://go.dev/play/p/BwEb8Lm4pb6

Aaron

Reply all
Reply to author
Forward
0 new messages