mirror of
https://github.com/golang/go
synced 2024-10-01 18:38:34 -06:00
fmt: handle %X like %x for byte type arrays and slices
Treat the verb %X in the same special way as %q, %s and %x are for arrays and slices with byte type elements. Modify input for tests so the result of %x and %X is distinct. Change-Id: I38d227755e98c7fad5e4adc2f603c6873aa910fd Reviewed-on: https://go-review.googlesource.com/20516 Run-TryBot: Rob Pike <r@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
80f2aff9ef
commit
c45c515348
@ -122,9 +122,11 @@ var bslice = barray[:]
|
||||
|
||||
type byteStringer byte
|
||||
|
||||
func (byteStringer) String() string { return "X" }
|
||||
func (byteStringer) String() string {
|
||||
return "X"
|
||||
}
|
||||
|
||||
var byteStringerSlice = []byteStringer{97, 98, 99, 100}
|
||||
var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'}
|
||||
|
||||
type byteFormatter byte
|
||||
|
||||
@ -132,7 +134,7 @@ func (byteFormatter) Format(f State, _ rune) {
|
||||
Fprint(f, "X")
|
||||
}
|
||||
|
||||
var byteFormatterSlice = []byteFormatter{97, 98, 99, 100}
|
||||
var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
|
||||
|
||||
var fmtTests = []struct {
|
||||
fmt string
|
||||
@ -706,7 +708,8 @@ 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"},
|
||||
{"%x", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656c6c6f"},
|
||||
{"%X", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656C6C6F"},
|
||||
{"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
|
||||
{"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
|
||||
{"%v", renamedFloat32(22), "22"},
|
||||
@ -933,19 +936,21 @@ var fmtTests = []struct {
|
||||
{"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
|
||||
|
||||
// []T where type T is a byte with a Stringer method.
|
||||
{"%v", byteStringerSlice, "[X X X X]"},
|
||||
{"%s", byteStringerSlice, "abcd"},
|
||||
{"%q", byteStringerSlice, "\"abcd\""},
|
||||
{"%x", byteStringerSlice, "61626364"},
|
||||
{"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x61, 0x62, 0x63, 0x64}"},
|
||||
{"%v", byteStringerSlice, "[X X X X X]"},
|
||||
{"%s", byteStringerSlice, "hello"},
|
||||
{"%q", byteStringerSlice, "\"hello\""},
|
||||
{"%x", byteStringerSlice, "68656c6c6f"},
|
||||
{"%X", byteStringerSlice, "68656C6C6F"},
|
||||
{"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x68, 0x65, 0x6c, 0x6c, 0x6f}"},
|
||||
|
||||
// And the same for Formatter.
|
||||
{"%v", byteFormatterSlice, "[X X X X]"},
|
||||
{"%s", byteFormatterSlice, "abcd"},
|
||||
{"%q", byteFormatterSlice, "\"abcd\""},
|
||||
{"%x", byteFormatterSlice, "61626364"},
|
||||
{"%v", byteFormatterSlice, "[X X X X X]"},
|
||||
{"%s", byteFormatterSlice, "hello"},
|
||||
{"%q", byteFormatterSlice, "\"hello\""},
|
||||
{"%x", byteFormatterSlice, "68656c6c6f"},
|
||||
{"%X", byteFormatterSlice, "68656C6C6F"},
|
||||
// This next case seems wrong, but the docs say the Formatter wins here.
|
||||
{"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X}"},
|
||||
{"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X, X}"},
|
||||
|
||||
// reflect.Value handled specially in Go 1.5, making it possible to
|
||||
// see inside non-exported fields (which cannot be accessed with Interface()).
|
||||
|
@ -894,12 +894,14 @@ BigSwitch:
|
||||
p.printValue(value, verb, depth+1)
|
||||
}
|
||||
case reflect.Array, reflect.Slice:
|
||||
// Byte slices are special:
|
||||
// Byte arrays and slices are special:
|
||||
// - Handle []byte (== []uint8) with fmtBytes.
|
||||
// - Handle []T, where T is a named byte type, with fmtBytes only
|
||||
// for the s, q, an x verbs. For other verbs, T might be a
|
||||
// for the s, q, x and X verbs. For other verbs, T might be a
|
||||
// Stringer, so we use printValue to print each element.
|
||||
if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 && (typ.Elem() == byteType || verb == 's' || verb == 'q' || verb == 'x') {
|
||||
typ := f.Type()
|
||||
if typ.Elem().Kind() == reflect.Uint8 &&
|
||||
(typ.Elem() == byteType || verb == 's' || verb == 'q' || verb == 'x' || verb == 'X') {
|
||||
var bytes []byte
|
||||
if f.Kind() == reflect.Slice {
|
||||
bytes = f.Bytes()
|
||||
@ -918,7 +920,7 @@ BigSwitch:
|
||||
break
|
||||
}
|
||||
if p.fmt.sharpV {
|
||||
p.buf.WriteString(value.Type().String())
|
||||
p.buf.WriteString(typ.String())
|
||||
if f.Kind() == reflect.Slice && f.IsNil() {
|
||||
p.buf.WriteString(nilParenString)
|
||||
break
|
||||
|
Loading…
Reference in New Issue
Block a user