New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
spec: be clear about the meaning of _ methods in interfaces #6604
Labels
Comments
go/types now implements the approach used by gccgo: blank methods in interfaces are not treated differently from methods with non-blank names, i.e., at most one blank method is permitted. There's at least some support for this approach in the spec since it says: "As with all method sets, in an interface type, each method must have a unique name." And - in contrast to the language about struct fields - it does not explicitly exclude blank names from the uniqueness requirement. |
See also related issue #6606 (for cmd/gc). |
Regarding initial comments 2a, 2b: Interface assignment is based on method sets, not interface type identity; there's no place where interface type identity (rather than the respective method sets matter). Thus, the initial list of possible approaches is flawed. There seem to be only two viable approaches: 1) gccgo approach: all method names (incl. _ methods) must be unique in an interface. That is, an interface may have at most one blank method. Because blank methods cannot be declared for non-interface types, no concrete type can ever implement such an interface. Because blank methods can be declared for interface types, the following code would be legal (albeit pointless): type I1 interface { _() } type I2 interface { _() } var i1 I1 var i2 I2 i1 = i2 i2 = i1 Interfaces may be embedded, so a blank method may be embedded as well. As with all other interface method names, declaring 2 blank methods would lead to a double-declaration error. Open question in this approach: Is the blank identifier exportable? That is, could one embed an imported interface with a blank method in an interface with another blank method? 2) Disallow blank methods in interfaces altogether. This seems to be the simplest approach but is somewhat "irregular" - we allow blank identifiers pretty much everywhere else. With this approach we would lose the ability to declare an interface that cannot be implemented by any type; however that seems not a very useful feature in the first place. |
Regarding #7: Blank identifiers are not capital letters and thus not exported. And there's a 3rd option: 3) All non-blank method names in an interface must be unique. Blank methods are ignored and are not part of the method set. This option might be closest in behavior to how declarations handle blank names, but slightly different from how blank fields are handled in structs (blank fields are part of the struct for size and type identity purposes). This option would permit interfaces with complete (and checked) method signatures, but otherwise "invisible" methods, which might be useful during development. On the other hand, one could just comment such methods out temporarily. |
See also issue #8060 (for go.tools/go/types). |
CL https://golang.org/cl/99410046 mentions this issue. |
This issue was closed by revision 2c83f1e. Status changed to Fixed. |
wheatman
pushed a commit
to wheatman/go-akaros
that referenced
this issue
Jun 25, 2018
The spec was unclear about whether blank methods should be permitted in interface types. gccgo permits at most one, gc crashes if there are more than one, go/types permits at most one. Discussion: Since method sets of non-interface types never contain methods with blank names (blank methods are never declared), it is impossible to satisfy an interface with a blank method. It is possible to declare variables of assignable interface types (but not necessarily identical types) containing blank methods, and assign those variables to each other, but the values of those variables can only be nil. There appear to be two "reasonable" alternatives: 1) Permit at most one blank method (since method names must be unique), and consider it part of the interface. This is what appears to happen now, with corner-case bugs. Such interfaces can never be implemented. 2) Permit arbitrary many blank methods but ignore them. This appears to be closer to the handling of blank identifiers in declarations. However, an interface type literal is not a declaration (it's a type literal). Also, for struct types, blank identifiers are not ignored; so the analogy with declarations is flawed. Both these alternatives don't seem to add any benefit and are likely (if only slightly) more complicated to explain and implement than disallowing blank methods in interfaces altogether. Fixes golang#6604. LGTM=r, rsc, iant R=r, rsc, ken, iant CC=golang-codereviews https://golang.org/cl/99410046
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
The text was updated successfully, but these errors were encountered: