1
0
mirror of https://github.com/golang/go synced 2024-11-21 20:54:45 -07:00

go spec: change def. of "type compatibility" to be non-recursive

and adjust conversion rules.

Also:
- clarification of type identity (no language change)
- adjust special rules for channel assignment/comparison to
  require identical element types (in correspondence to non-
  recursiveness of type compatibility)

R=rsc, iant, ken2, r
CC=golang-dev
https://golang.org/cl/1376042
This commit is contained in:
Robert Griesemer 2010-05-28 14:17:30 -07:00
parent 2bb59fd71a
commit 63f014910d

View File

@ -3,7 +3,7 @@
<!-- <!--
Todo Todo
[ ] clarify: two equal lowercase identifiers from different packages denote different objects [ ] clarify: two equal lower-case identifiers from different packages denote different objects
[ ] need language about function/method calls and parameter passing rules [ ] need language about function/method calls and parameter passing rules
[ ] last paragraph of #Assignments (constant promotion) should be elsewhere [ ] last paragraph of #Assignments (constant promotion) should be elsewhere
and mention assignment to empty interface. and mention assignment to empty interface.
@ -1236,10 +1236,10 @@ Identical types are always compatible, but compatible types need not be identica
<p> <p>
Two named types are identical if their type names originate in the same Two named types are identical if their type names originate in the same
type declaration (§<a href="#Declarations_and_scope">Declarations and scope</a>). A named and an unnamed type type declaration (§<a href="#Declarations_and_scope">Declarations and scope</a>).
are never identical. Two unnamed types are identical if the corresponding A named and an unnamed type are always different. Two unnamed types are identical
type literals have the same literal structure and corresponding components have if the corresponding type literals are identical; that is if they have the same
identical types. In detail: literal structure and corresponding components have identical types. In detail:
</p> </p>
<ul> <ul>
@ -1250,7 +1250,8 @@ identical types. In detail:
<li>Two struct types are identical if they have the same sequence of fields, <li>Two struct types are identical if they have the same sequence of fields,
and if corresponding fields have the same names and identical types. and if corresponding fields have the same names and identical types.
Two anonymous fields are considered to have the same name.</li> Two anonymous fields are considered to have the same name. Lower-case field
names from different packages are always different.</li>
<li>Two pointer types are identical if they have identical base types.</li> <li>Two pointer types are identical if they have identical base types.</li>
@ -1262,8 +1263,8 @@ identical types. In detail:
Parameter and result names are not required to match.</li> Parameter and result names are not required to match.</li>
<li>Two interface types are identical if they have the same set of methods <li>Two interface types are identical if they have the same set of methods
with the same names and identical function types. The order with the same names and identical function types. Lower-case method names from
of the methods is irrelevant.</li> different packages are always different. The order of the methods is irrelevant.</li>
<li>Two map types are identical if they have identical key and value types.</li> <li>Two map types are identical if they have identical key and value types.</li>
@ -1274,11 +1275,9 @@ identical types. In detail:
<h4 id="Type_compatibility">Type compatibility</h4> <h4 id="Type_compatibility">Type compatibility</h4>
<p> <p>
Type compatibility is less stringent than type identity: a named and an unnamed Type compatibility is less stringent than type identity: All identical types are
type are compatible if the respective type literals are compatible. compatible, but additionally a named and an unnamed type are compatible if the
In all other respects, the definition of type compatibility is the respective type literals are identical.
same as for type identity listed above but with ``compatible''
substituted for ``identical''.
</p> </p>
<p> <p>
@ -1320,12 +1319,14 @@ These types are compatible:
T0 and T0 T0 and T0
T0 and []string T0 and []string
T3 and struct { a int; c int } T3 and struct { a int; c int }
T4 and func(x int, y float) *[]string T4 and func(x int, y float) (result *T0)
</pre> </pre>
<p> <p>
<code>T2</code> and <code>struct { a, c int }</code> are incompatible because <code>T2</code> and <code>struct { a, c int }</code> are incompatible because
they have different field names. they have different field names; <code>T4</code> and
<code>func(x int, y float) *[]string</code> are incompatible because the
respective type literals are different.
</p> </p>
<h3 id="Assignment_compatibility">Assignment compatibility</h3> <h3 id="Assignment_compatibility">Assignment compatibility</h3>
@ -1345,7 +1346,7 @@ with a type <code>T</code> if one or more of the following conditions applies:
</li> </li>
<li> <li>
<code>V</code> is a bidirectional channel and <code>T</code> is a channel type <code>V</code> is a bidirectional channel and <code>T</code> is a channel type
with compatible element type and at least one of <code>V</code> or <code>T</code> is unnamed. with identical element type and at least one of <code>V</code> or <code>T</code> is unnamed.
</li> </li>
</ul> </ul>
@ -1418,7 +1419,7 @@ Function values are equal if they refer to the same function.
Channel and map values are equal if they were created by the same call to <code>make</code> Channel and map values are equal if they were created by the same call to <code>make</code>
<a href="#Making_slices">Making slices</a>, maps, and channels). <a href="#Making_slices">Making slices</a>, maps, and channels).
When comparing two values of channel type, the channel value types When comparing two values of channel type, the channel value types
must be compatible but the channel direction is ignored. must be identical but the channel direction is ignored.
</li> </li>
<li> <li>
Interface values may be compared if they have compatible static types. Interface values may be compared if they have compatible static types.
@ -2550,7 +2551,7 @@ The notation <code>x.(T)</code> is called a <i>type assertion</i>.
<p> <p>
More precisely, if <code>T</code> is not an interface type, <code>x.(T)</code> asserts More precisely, if <code>T</code> is not an interface type, <code>x.(T)</code> asserts
that the dynamic type of <code>x</code> is identical to the type <code>T</code> that the dynamic type of <code>x</code> is identical to the type <code>T</code>
<a href="#Type_identity_and_compatibility">Type identity and compatibility</a>). <a href="#Type_identity">Type identity and compatibility</a>).
If <code>T</code> is an interface type, <code>x.(T)</code> asserts that the dynamic type If <code>T</code> is an interface type, <code>x.(T)</code> asserts that the dynamic type
of <code>x</code> implements the interface <code>T</code><a href="#Interface_types">Interface types</a>). of <code>x</code> implements the interface <code>T</code><a href="#Interface_types">Interface types</a>).
</p> </p>
@ -2642,7 +2643,7 @@ if Join(Split(value, len(value)/2)) != value {
<p> <p>
A method call <code>x.m()</code> is valid if the method set of A method call <code>x.m()</code> is valid if the method set of
(the type of) <code>x</code> contains <code>m</code> and the (the type of) <code>x</code> contains <code>m</code> and the
argument list is compatible with the parameter list of <code>m</code>. argument list can be assigned to the parameter list of <code>m</code>.
If <code>x</code> is <a href="#Address_operators">addressable</a> and <code>&amp;x</code>'s method If <code>x</code> is <a href="#Address_operators">addressable</a> and <code>&amp;x</code>'s method
set contains <code>m</code>, <code>x.m()</code> is shorthand set contains <code>m</code>, <code>x.m()</code> is shorthand
for <code>(&amp;x).m()</code>: for <code>(&amp;x).m()</code>:
@ -3263,12 +3264,21 @@ If the type starts with an operator it must be parenthesized:
</pre> </pre>
<p> <p>
In general, a conversion succeeds if the value of <code>x</code> is In general, a conversion is permitted if
<a href="#Assignment_compatibility">assignment compatible</a> with type <code>T</code>, </p>
or if the value would be assignment compatible with type <code>T</code> if the <ol>
value's type, or <code>T</code>, or any of their component types were unnamed. <li>
Usually, such a conversion changes the type but not the representation of the value the value of <code>x</code> would be
of <code>x</code> and thus has no run-time cost. <a href="#Assignment_compatibility">assignment compatible</a> with type
<code>T</code> if <code>T</code> were unnamed
</li>
<li>
<code>x</code> is of an unnamed pointer type and type <code>T</code> is another
unnamed pointer type and the previous rule applies to the pointer base types.
</li>
</ol>
<p>
Such a conversion changes the type but not the representation of <code>x</code>.
</p> </p>
<p> <p>
@ -4478,10 +4488,10 @@ m := make(map[string] int, 100) // map with initial space for 100 elements
<h3 id="Copying_slices">Copying slices</h3> <h3 id="Copying_slices">Copying slices</h3>
<p> <p>
The built-in function <code>copy</code> copies array or slice elements from The built-in function <code>copy</code> copies slice elements from
a source <code>src</code> to a destination <code>dst</code> and returns the a source <code>src</code> to a destination <code>dst</code> and returns the
number of elements copied. Source and destination may overlap. number of elements copied. Source and destination may overlap.
Both arguments must have the same element type <code>T</code> and must be Both arguments must have identical element type <code>T</code> and must be
<a href="#Assignment_compatibility">assignment compatible</a> to a slice <a href="#Assignment_compatibility">assignment compatible</a> to a slice
of type <code>[]T</code>. The number of arguments copied is the minimum of of type <code>[]T</code>. The number of arguments copied is the minimum of
<code>len(src)</code> and <code>len(dst)</code>. <code>len(src)</code> and <code>len(dst)</code>.
@ -4498,7 +4508,7 @@ Examples:
<pre> <pre>
var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7} var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
var s = make([]int, 6) var s = make([]int, 6)
n1 := copy(s, &amp;a) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5} n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5} n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
</pre> </pre>