mirror of
https://github.com/golang/go
synced 2024-11-26 08:07:57 -07:00
handle the nil interface better in reflect and print
R=rsc DELTA=25 (19 added, 0 deleted, 6 changed) OCL=20985 CL=20985
This commit is contained in:
parent
793a6effcf
commit
ac09eb4f49
@ -307,10 +307,13 @@ func parsenum(s string, start, end int) (n int, got bool, newi int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *P) printField(field reflect.Value) (was_string bool) {
|
func (p *P) printField(field reflect.Value) (was_string bool) {
|
||||||
if stringer, ok := field.Interface().(String); ok {
|
inter := field.Interface();
|
||||||
|
if inter != nil {
|
||||||
|
if stringer, ok := inter.(String); ok {
|
||||||
p.addstr(stringer.String());
|
p.addstr(stringer.String());
|
||||||
return false; // this value is not a string
|
return false; // this value is not a string
|
||||||
}
|
}
|
||||||
|
}
|
||||||
s := "";
|
s := "";
|
||||||
switch field.Kind() {
|
switch field.Kind() {
|
||||||
case reflect.BoolKind:
|
case reflect.BoolKind:
|
||||||
@ -363,6 +366,14 @@ func (p *P) printField(field reflect.Value) (was_string bool) {
|
|||||||
p.add('{');
|
p.add('{');
|
||||||
p.doprint(field, true, false);
|
p.doprint(field, true, false);
|
||||||
p.add('}');
|
p.add('}');
|
||||||
|
case reflect.InterfaceKind:
|
||||||
|
inter := field.(reflect.InterfaceValue).Get();
|
||||||
|
if inter == nil {
|
||||||
|
s = "<nil>"
|
||||||
|
} else {
|
||||||
|
// should never happen since a non-nil interface always has a type
|
||||||
|
s = "<non-nil interface>";
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
s = "?" + field.Type().String() + "?";
|
s = "?" + field.Type().String() + "?";
|
||||||
}
|
}
|
||||||
@ -421,8 +432,9 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
|
|||||||
}
|
}
|
||||||
field := getField(v, fieldnum);
|
field := getField(v, fieldnum);
|
||||||
fieldnum++;
|
fieldnum++;
|
||||||
if c != 'T' { // don't want thing to describe itself if we're asking for its type
|
inter := field.Interface();
|
||||||
if formatter, ok := field.Interface().(Format); ok {
|
if inter != nil && c != 'T' { // don't want thing to describe itself if we're asking for its type
|
||||||
|
if formatter, ok := inter.(Format); ok {
|
||||||
formatter.Format(p, c);
|
formatter.Format(p, c);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -340,6 +340,8 @@ func (t *InterfaceTypeStruct) Len() int {
|
|||||||
return len(t.field)
|
return len(t.field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var NilInterface = NewInterfaceTypeStruct("nil", "", new([]Field, 0));
|
||||||
|
|
||||||
// -- Func
|
// -- Func
|
||||||
|
|
||||||
export type FuncType interface {
|
export type FuncType interface {
|
||||||
@ -834,6 +836,10 @@ func (p *Parser) Type(name string) *StubType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export func ParseTypeString(name, typestring string) Type {
|
export func ParseTypeString(name, typestring string) Type {
|
||||||
|
if typestring == "" {
|
||||||
|
// If the typestring is empty, it represents (the type of) a nil interface value
|
||||||
|
return NilInterface
|
||||||
|
}
|
||||||
p := new(Parser);
|
p := new(Parser);
|
||||||
p.str = typestring;
|
p.str = typestring;
|
||||||
p.Next();
|
p.Next();
|
||||||
|
@ -59,6 +59,7 @@ type Creator *(typ Type, addr Addr) Value
|
|||||||
export type MissingValue interface {
|
export type MissingValue interface {
|
||||||
Kind() int;
|
Kind() int;
|
||||||
Type() Type;
|
Type() Type;
|
||||||
|
Addr() Addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
type MissingValueStruct struct {
|
type MissingValueStruct struct {
|
||||||
@ -66,7 +67,7 @@ type MissingValueStruct struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MissingCreator(typ Type, addr Addr) Value {
|
func MissingCreator(typ Type, addr Addr) Value {
|
||||||
return &MissingValueStruct{ Common{IntKind, typ, addr} }
|
return &MissingValueStruct{ Common{MissingKind, typ, addr} }
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Int
|
// -- Int
|
||||||
|
Loading…
Reference in New Issue
Block a user