From: Rob Pike Date: Mon, 16 Aug 2010 22:34:40 +0000 (+1000) Subject: fmt/print: remove a TODO regarding printing renamed byte slices. X-Git-Tag: weekly.2010-08-25~49 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=316961c1724deeb6e79f700f24bde345e0d5d992;p=gostls13.git fmt/print: remove a TODO regarding printing renamed byte slices. the solution must work around a weakness in the reflection library: there is no way to do type-safe conversions under reflection. R=rsc CC=golang-dev https://golang.org/cl/2000041 --- diff --git a/src/pkg/fmt/fmt_test.go b/src/pkg/fmt/fmt_test.go index 57fef2197c..97fd497fbd 100644 --- a/src/pkg/fmt/fmt_test.go +++ b/src/pkg/fmt/fmt_test.go @@ -334,8 +334,7 @@ var fmttests = []fmtTest{ fmtTest{"%X", renamedUint64(17), "11"}, fmtTest{"%o", renamedUintptr(18), "22"}, fmtTest{"%x", renamedString("thing"), "7468696e67"}, - // TODO: It would be nice if this one worked, but it's hard. - // fmtTest{"%q", renamedBytes([]byte("hello")), `"hello"`}, + fmtTest{"%q", renamedBytes([]byte("hello")), `"hello"`}, fmtTest{"%v", renamedFloat(11), "11"}, fmtTest{"%v", renamedFloat32(22), "22"}, fmtTest{"%v", renamedFloat64(33), "33"}, diff --git a/src/pkg/fmt/print.go b/src/pkg/fmt/print.go index bf13a7c9c1..b272c26a45 100644 --- a/src/pkg/fmt/print.go +++ b/src/pkg/fmt/print.go @@ -697,6 +697,22 @@ BigSwitch: return p.printField(value.Interface(), verb, plus, goSyntax, depth+1) } case reflect.ArrayOrSliceValue: + // Byte slices are special. + if f.Type().(reflect.ArrayOrSliceType).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.Elem(i).(*reflect.UintValue).Get()) + } + p.fmtBytes(bytes, verb, goSyntax, depth, field) + return verb == 's' + } if goSyntax { p.buf.WriteString(reflect.Typeof(field).String()) p.buf.WriteByte('{') @@ -804,7 +820,7 @@ func (p *pp) doPrintf(format string, a []interface{}) { i += w // percent is special - absorbs no operand if c == '%' { - p.buf.WriteByte('%') // TODO: should we bother with width & prec? + p.buf.WriteByte('%') // We ignore width and prec. continue } if fieldnum >= len(a) { // out of operands