aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-08-24 22:00:32 -0700
committerIan Lance Taylor <iant@golang.org>2020-08-25 19:54:24 +0000
commiteb38a3580cbb12e243aeca3216bf236c143549f0 (patch)
treec7355dfbf709a16a3b386175f2966612f057c029
parentbfd574d8f661ae0dc41427d0fafe364dc0eaf57e (diff)
downloadgo-x-proposal-eb38a3580cbb12e243aeca3216bf236c143549f0.tar.xz
design: type parameters: type lists don't imply methods
Change-Id: If45d9b9b75ca2cda1feb4a9ba645648b2e35763e Reviewed-on: https://go-review.googlesource.com/c/proposal/+/250377 Reviewed-by: Robert Griesemer <gri@golang.org>
-rw-r--r--design/go2draft-type-parameters.md67
1 files changed, 67 insertions, 0 deletions
diff --git a/design/go2draft-type-parameters.md b/design/go2draft-type-parameters.md
index 4c5eb44..987c1e6 100644
--- a/design/go2draft-type-parameters.md
+++ b/design/go2draft-type-parameters.md
@@ -1704,6 +1704,73 @@ func (mi MyInt) String() string {
}
```
+#### Types with methods in type lists
+
+Using a type list permits a generic function to use an operation that
+is permitted by all the types in the type list.
+However, that does not apply to methods.
+Even if every type in the type list supports the same method with the
+same signature, the generic function may not call that method.
+It may only call methods that are explicitly listed in the constraint,
+as explained in the previous section.
+
+Here is an example of types with the same method.
+This example is invalid.
+Even though both `MyInt` and `MyFloat` have a `String` method, the
+`ToString` function is not permitted to call that method.
+
+```Go
+// MyInt has a String method.
+type MyInt int
+
+func (i MyInt) String() string {
+ return strconv.Itoa(int(i))
+}
+
+// MyFloat also has a String method.
+type MyFloat float64
+
+func (f MyFloat) String() string {
+ return strconv.FormatFloat(float64(f), 'g', -1, 64)
+}
+
+// MyIntOrFloat is a type constraint that accepts MyInt or MyFloat.
+type MyIntOrFloat interface {
+ type MyInt, MyFloat
+}
+
+// ToString converts a value to a string.
+// This function is INVALID.
+func ToString[T MyIntOrFloat](v T) string {
+ return v.String() // INVALID
+}
+```
+
+To permit the `String` method to be called, it must be explicitly
+listed in the constraint.
+
+```Go
+// MyIntOrFloatStringer accepts MyInt or MyFloat, and defines a String
+// method. Note that both MyInt and MyFloat have a String method.
+// If either did not have a String method, they would not satisfy the
+// constraint even though the type list lists them. To satisfy a
+// constraint a type must both match the type list (if any) and
+// implement all the methods (if any).
+type MyIntOrFloatStringer interface {
+ type MyInt, MyFloat
+ String() string
+}
+
+// ToString2 convers a value to a string.
+func ToString2[T MyIntOrFloatStringer](v T) string {
+ return v.String()
+}
+```
+
+The reason for this rule is to simplify complex cases involving
+embedded type parameters in which it may not be immediately clear
+whether the type has a particular method or not.
+
#### Composite types in constraints
A type in a constraint may be a type literal.