[generics]: Pointer methods in interfaces used as constraints?

111 views
Skip to first unread message

Patrick Smith

unread,
Aug 15, 2020, 12:32:01 AM8/15/20
to golang-nuts
https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#pointer-method-example has this example:

// Setter2 is a type constraint that requires that the type
// implement a Set method that sets the value from a string,
// and also requires that the type be a pointer to its type parameter.
type Setter2(type B) interface {
Set(string)
type *B
}
// FromStrings2 takes a slice of strings and returns a slice of T,
// calling the Set method to set each returned value.
//
// We use two different type parameters so that we can return
// a slice of type T but call methods on *T aka PT.
// The Setter2 constraint ensures that PT is a pointer to T.
func FromStrings2(type T interface{}, PT Setter2(T))(s []string) []T {
result := make([]T, len(s))
for i, v := range s {
// The type of &result[i] is *T which is in the type list
// of Setter2, so we can convert it to PT.
p := PT(&result[i])
// PT has a Set method.
p.Set(v)
}
return result
}

I wonder if it might be worthwhile to allow specifying pointer methods in interfaces, so that we could write instead

type Setter3 interface {
// For type T to implement Setter3, *T must have a Set method.
* Set(string)
}

func FromStrings3(type T Setter3(T))(s []string) []T {
result := make([]T, len(s))
for i, v := range s {
result[i].Set(v)
}
}

This is simpler in two ways: FromStrings3 only needs one interface constraint, and it does not need to convert &result[i] to a type parameter, but can call result[i].Set(v) directly.

I imagine interfaces containing pointer methods should be used only as constraints on type parameters, not as normal interfaces.

I have no idea if such cases arise often enough to make this idea worthwhile.

Ian Lance Taylor

unread,
Aug 16, 2020, 1:06:53 AM8/16/20
to Patrick Smith, golang-nuts
This suggestion is a little bit like the pointer methods we had in an
earlier version of the design draft
(https://go.googlesource.com/proposal/+/572fea69936c3f25a99860fce22aeb23a3263ca3/design/go2draft-type-parameters.md#pointer-methods).

I'm not sure how that would work if such an interface type were used
other than as a type constraint (of course we could forbid that case).
An interface currently holds either a pointer or a value. If the
interface says that the method must be on the pointer type, then
presumably the interface will hold a value. But then what address do
we take to call the method? Taking the address of the value stored
inside the interface would mean that an interface was a reference type
rather than a value type. I think that would be a subtle distinction
that might increase confusion when using the language. Though
admittedly the points in this area are already rather subtle (e.g.,
the FAQ answer https://golang.org/doc/faq#pointer_to_interface).

That side, at the moment I think that the constraint type inference
idea is more versatile, as it works for types other than pointers.

Ian
Reply all
Reply to author
Forward
0 new messages