1
0
mirror of https://github.com/golang/go synced 2024-11-18 15:54:42 -07:00

fmt: improve go syntax handling of byte-derived arrays and slices

Fixes #4685.

R=golang-dev, adg, remyoudompheng, rsc
CC=golang-dev
https://golang.org/cl/7205047
This commit is contained in:
Robert Daniel Kortschak 2013-01-30 17:53:53 -08:00 committed by Russ Cox
parent eea0f19990
commit 92bc896909
2 changed files with 35 additions and 15 deletions

View File

@ -105,6 +105,9 @@ func (p *P) String() string {
return "String(p)"
}
var barray = [5]renamedUint8{1, 2, 3, 4, 5}
var bslice = barray[:]
var b byte
var fmttests = []struct {
@ -332,14 +335,18 @@ var fmttests = []struct {
// arrays
{"%v", array, "[1 2 3 4 5]"},
{"%v", iarray, "[1 hello 2.5 <nil>]"},
{"%v", barray, "[1 2 3 4 5]"},
{"%v", &array, "&[1 2 3 4 5]"},
{"%v", &iarray, "&[1 hello 2.5 <nil>]"},
{"%v", &barray, "&[1 2 3 4 5]"},
// slices
{"%v", slice, "[1 2 3 4 5]"},
{"%v", islice, "[1 hello 2.5 <nil>]"},
{"%v", bslice, "[1 2 3 4 5]"},
{"%v", &slice, "&[1 2 3 4 5]"},
{"%v", &islice, "&[1 hello 2.5 <nil>]"},
{"%v", &bslice, "&[1 2 3 4 5]"},
// complexes with %v
{"%v", 1 + 2i, "(1+2i)"},
@ -382,6 +389,8 @@ var fmttests = []struct {
{"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
{"%#v", map[int]byte{}, `map[int]uint8{}`},
{"%#v", "foo", `"foo"`},
{"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
{"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
// slices with other formats
{"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
@ -407,6 +416,9 @@ var fmttests = []struct {
{"%x", renamedString("thing"), "7468696e67"},
{"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
{"%q", renamedBytes([]byte("hello")), `"hello"`},
{"%x", []renamedUint8{'a', 'b', 'c'}, "616263"},
{"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
{"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
{"%v", renamedFloat32(22), "22"},
{"%v", renamedFloat64(33), "33"},
{"%v", renamedComplex64(3 + 4i), "(3+4i)"},

View File

@ -545,10 +545,15 @@ func (p *pp) fmtString(v string, verb rune, goSyntax bool) {
}
}
func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) {
func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, typ reflect.Type, depth int) {
if verb == 'v' || verb == 'd' {
if goSyntax {
p.buf.Write(bytesBytes)
if typ == nil {
p.buf.Write(bytesBytes)
} else {
p.buf.WriteString(typ.String())
p.buf.WriteByte('{')
}
} else {
p.buf.WriteByte('[')
}
@ -793,7 +798,7 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
p.fmtString(f, verb, goSyntax)
wasString = verb == 's' || verb == 'v'
case []byte:
p.fmtBytes(f, verb, goSyntax, depth)
p.fmtBytes(f, verb, goSyntax, nil, depth)
wasString = verb == 's'
default:
// Restore flags in case handleMethods finds a Formatter.
@ -939,19 +944,22 @@ BigSwitch:
}
case reflect.Array, reflect.Slice:
// Byte slices are special.
if f.Type().Elem().Kind() == reflect.Uint8 {
// We know it's a slice of bytes, but we also know it does not have static type
// []byte, or it would have been caught above. Therefore we cannot convert
// it directly in the (slightly) obvious way: f.Interface().([]byte); it doesn't have
// that type, and we can't write an expression of the right type and do a
// conversion because we don't have a static way to write the right type.
// So we build a slice by hand. This is a rare case but it would be nice
// if reflection could help a little more.
bytes := make([]byte, f.Len())
for i := range bytes {
bytes[i] = byte(f.Index(i).Uint())
if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 {
var bytes []byte
if f.Kind() == reflect.Slice {
bytes = f.Bytes()
} else if f.CanAddr() {
bytes = f.Slice(0, f.Len()).Bytes()
} else {
// We have an array, but we cannot Slice() a non-addressable array,
// so we build a slice by hand. This is a rare case but it would be nice
// if reflection could help a little more.
bytes = make([]byte, f.Len())
for i := range bytes {
bytes[i] = byte(f.Index(i).Uint())
}
}
p.fmtBytes(bytes, verb, goSyntax, depth)
p.fmtBytes(bytes, verb, goSyntax, typ, depth)
wasString = verb == 's'
break
}