1
0
mirror of https://github.com/golang/go synced 2024-11-25 23:17:58 -07:00

update reflect for upcoming interface representation change.

test case for new change.

both work with the current compiler too.

R=r
DELTA=150  (145 added, 2 deleted, 3 changed)
OCL=28703
CL=28715
This commit is contained in:
Russ Cox 2009-05-12 16:08:16 -07:00
parent daf44e2fa5
commit 28516d4c78
3 changed files with 151 additions and 4 deletions

View File

@ -782,7 +782,16 @@ type interfaceValueStruct struct {
} }
func (v *interfaceValueStruct) Get() interface{} { func (v *interfaceValueStruct) Get() interface{} {
return *(*interface{})(v.addr) // There are two different representations of interface values,
// one if the interface type has methods and one if it doesn't.
// These two representations require different expressions
// to extract correctly.
if v.Type().(InterfaceType).Len() == 0 {
// Extract as interface value without methods.
return *(*interface{})(v.addr)
}
// Extract from v.addr as interface value with methods.
return *(*interface{ m() })(v.addr)
} }
func (v *interfaceValueStruct) Value() Value { func (v *interfaceValueStruct) Value() Value {

140
test/interface11.go Normal file
View File

@ -0,0 +1,140 @@
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Check uses of all the different interface
// conversion runtime functions.
package main
type Stringer interface { String() string }
type StringLengther interface { String() string; Length() int }
type Empty interface { }
type T string
func (t T) String() string {
return string(t);
}
func (t T) Length() int {
return len(t);
}
type U string
func (u U) String() string {
return string(u);
}
var t = T("hello")
var u = U("goodbye")
var e Empty
var s Stringer = t
var sl StringLengther = t
var i int
var ok bool
func hello(s string) {
if s != "hello" {
panic("not hello: ", s);
}
}
func five(i int) {
if i != 5 {
panic("not 5: ", i);
}
}
func true(ok bool) {
if !ok {
panic("not true");
}
}
func false(ok bool) {
if ok {
panic("not false");
}
}
func main() {
// T2I
s = t;
hello(s.String());
// I2T
t = s.(T);
hello(t.String());
// T2E
e = t;
// E2T
t = e.(T);
hello(t.String());
// T2I again
sl = t;
hello(sl.String());
five(sl.Length());
// I2I static
s = sl;
hello(s.String());
// I2I dynamic
sl = s.(StringLengther);
hello(sl.String());
five(sl.Length());
// I2E (and E2T)
e = s;
hello(e.(T).String());
// E2I
s = e.(Stringer);
hello(s.String());
// I2T2 true
t, ok = s.(T);
true(ok);
hello(t.String());
// I2T2 false
var u1 U;
u1, ok = s.(U);
false(ok);
// I2I2 true
sl, ok = s.(StringLengther);
true(ok);
hello(sl.String());
five(sl.Length());
// I2I2 false (and T2I)
s = u;
sl, ok = s.(StringLengther);
false(ok);
// E2T2 true
t, ok = e.(T);
true(ok);
hello(t.String());
// E2T2 false
i, ok = e.(int);
false(ok);
// E2I2 true
sl, ok = e.(StringLengther);
true(ok);
hello(sl.String());
five(sl.Length());
// E2I2 false (and T2E)
e = u;
sl, ok = e.(StringLengther);
false(ok);
}

View File

@ -9,8 +9,6 @@
package main package main
import "os"
type I interface { M() int64 } type I interface { M() int64 }
type BigPtr struct { a, b, c, d int64 } type BigPtr struct { a, b, c, d int64 }
@ -72,6 +70,6 @@ func main() {
nonptrs(); nonptrs();
if bad { if bad {
os.Exit(1) println("BUG: interface4");
} }
} }