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:
parent
eea0f19990
commit
92bc896909
@ -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)"},
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user