}
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 {
--- /dev/null
+// $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);
+}
+
package main
-import "os"
-
type I interface { M() int64 }
type BigPtr struct { a, b, c, d int64 }
nonptrs();
if bad {
- os.Exit(1)
+ println("BUG: interface4");
}
}