Commit ac6ebfde authored by Russ Cox's avatar Russ Cox

add method Value() Value to InterfaceValue.

use Value() in print to print underlying value
from interface.

before:
	package main
	import "fmt"
	func main() {
		x := []interface{} {1, "hello", 2.5};
		fmt.Println(x[0], x[1], x[2], x);
	}

	1 hello 2.5 [<non-nil interface> <non-nil interface> <non-nil interface>]

after:
	1 hello 2.5 [1 hello 2.5]

R=r
DELTA=44  (22 added, 16 deleted, 6 changed)
OCL=27139
CL=27141
parent b80fdd1e
...@@ -29,7 +29,7 @@ type fmtTest struct { ...@@ -29,7 +29,7 @@ type fmtTest struct {
const b32 uint32 = 1<<32 - 1 const b32 uint32 = 1<<32 - 1
const b64 uint64 = 1<<64 - 1 const b64 uint64 = 1<<64 - 1
var array = []int{1, 2, 3, 4, 5} var array = []int{1, 2, 3, 4, 5}
var iarray = []interface{}{1, "hello", 2.5, nil}
var fmttests = []fmtTest{ var fmttests = []fmtTest{
// basic string // basic string
...@@ -80,10 +80,10 @@ var fmttests = []fmtTest{ ...@@ -80,10 +80,10 @@ var fmttests = []fmtTest{
fmtTest{ "% d", -12345, "-12345" }, fmtTest{ "% d", -12345, "-12345" },
// arrays // arrays
// TODO: when arrays work in interfaces, enable this line fmtTest{ "%v", array, "[1 2 3 4 5]" },
// and delete the TestArrayPrinter routine below fmtTest{ "%v", iarray, "[1 hello 2.5 <nil>]" },
// fmtTest{ "%v", array, "[1 2 3 4 5]" },
fmtTest{ "%v", &array, "&[1 2 3 4 5]" }, fmtTest{ "%v", &array, "&[1 2 3 4 5]" },
fmtTest{ "%v", &iarray, "&[1 hello 2.5 <nil>]" },
// old test/fmt_test.go // old test/fmt_test.go
fmtTest{ "%d", 1234, "1234" }, fmtTest{ "%d", 1234, "1234" },
...@@ -240,17 +240,3 @@ func TestStructPrinter(t *testing.T) { ...@@ -240,17 +240,3 @@ func TestStructPrinter(t *testing.T) {
} }
} }
} }
func TestArrayPrinter(t *testing.T) {
a := []int{1, 2, 3, 4, 5};
want := "[1 2 3 4 5]";
out := fmt.Sprintf("%v", a);
if out != want {
t.Errorf("Sprintf(%%v, array) = %q, want %q", out, want);
}
want = "&" + want;
out = fmt.Sprintf("%v", &a);
if out != want {
t.Errorf("Sprintf(%%v, &array) = %q, want %q", out, want);
}
}
...@@ -451,12 +451,11 @@ func (p *pp) printField(field reflect.Value) (was_string bool) { ...@@ -451,12 +451,11 @@ func (p *pp) printField(field reflect.Value) (was_string bool) {
} }
p.add('}'); p.add('}');
case reflect.InterfaceKind: case reflect.InterfaceKind:
inter := field.(reflect.InterfaceValue).Get(); value := field.(reflect.InterfaceValue).Value();
if inter == nil { if value == nil {
s = "<nil>" s = "<nil>"
} else { } else {
// should never happen since a non-nil interface always has a type return p.printField(value);
s = "<non-nil interface>";
} }
default: default:
s = "?" + field.Type().String() + "?"; s = "?" + field.Type().String() + "?";
......
...@@ -301,6 +301,16 @@ func TestInterfaceGet(t *testing.T) { ...@@ -301,6 +301,16 @@ func TestInterfaceGet(t *testing.T) {
assert(v3.Type().String(), "float"); assert(v3.Type().String(), "float");
} }
func TestInterfaceValue(t *testing.T) {
var inter struct { e interface{ } };
inter.e = 123.456;
v1 := reflect.NewValue(&inter);
v2 := v1.(reflect.PtrValue).Sub().(reflect.StructValue).Field(0);
assert(v2.Type().String(), "interface { }");
v3 := v2.(reflect.InterfaceValue).Value();
assert(v3.Type().String(), "float");
}
func TestCopyArray(t *testing.T) { func TestCopyArray(t *testing.T) {
a := []int{ 1, 2, 3, 4, 10, 9, 8, 7 }; a := []int{ 1, 2, 3, 4, 10, 9, 8, 7 };
b := []int{ 11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44 }; b := []int{ 11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44 };
......
...@@ -34,6 +34,8 @@ type Value interface { ...@@ -34,6 +34,8 @@ type Value interface {
Interface() interface {}; Interface() interface {};
} }
func NewValue(e interface{}) Value;
// commonValue fields and functionality for all values // commonValue fields and functionality for all values
type commonValue struct { type commonValue struct {
...@@ -744,6 +746,7 @@ func structCreator(typ Type, addr Addr) Value { ...@@ -744,6 +746,7 @@ func structCreator(typ Type, addr Addr) Value {
type InterfaceValue interface { type InterfaceValue interface {
Value; Value;
Get() interface {}; // Get the underlying interface{} value. Get() interface {}; // Get the underlying interface{} value.
Value() Value;
} }
type interfaceValueStruct struct { type interfaceValueStruct struct {
...@@ -754,6 +757,14 @@ func (v *interfaceValueStruct) Get() interface{} { ...@@ -754,6 +757,14 @@ func (v *interfaceValueStruct) Get() interface{} {
return *(*interface{})(v.addr) return *(*interface{})(v.addr)
} }
func (v *interfaceValueStruct) Value() Value {
i := v.Get();
if i == nil {
return nil;
}
return NewValue(i);
}
func interfaceCreator(typ Type, addr Addr) Value { func interfaceCreator(typ Type, addr Addr) Value {
return &interfaceValueStruct{ commonValue{InterfaceKind, typ, addr} } return &interfaceValueStruct{ commonValue{InterfaceKind, typ, addr} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment