-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fmt: empty byte slice prints one value with format "% 02x" #10430
Comments
So? https://play.golang.org/p/35pyRrGLXN
prints:
Are those leading zeros wrong too? The user asked for it to be zero-padded. |
I think while this is surprising, it isn't a bug as it works as documented in https://golang.org/pkg/fmt/: 0 pad with leading zeros rather than spaces; "% 08x" applied to an argument of type []byte doesn't mean "format the bytes in the argument with 8 hex characters per byte, separated by spaces." It means "format the bytes in the argument with 2 hex characters per byte, separated by spaces, and then pad the result with 0s on the left if the string has length less than 8." Thus, fmt.Printf("% 04x", []byte{}) first produces "" which is padded to "0000". Examples: https://play.golang.org/p/lvP2PBEdJZ |
"For compound operands such as slices and structs, the format applies to the elements of each operand, recursively, not to the operand as a whole. Thus %q will quote each element of a slice of strings, and %6.2f will control formatting for each element of a floating-point array." So for an empty slice it should print nothing. Fix coming. |
As brad asked, isn't this change effectively make width not applicable for string and byte slices? Should we mention that in docs? It seems, the previous behavior was adhering to the following statement in the docs. "For most values, width is the minimum number of runes to output, padding the formatted form with spaces if necessary." raj@rajender:~/go/src> cat ~/a.go import "fmt" func main() { raj@rajender:~/go/src> cat ~/a.go import "fmt" func main() { |
hi, the statement in the patch notes that the loop applies the padding is false. See a testcase like:
it works for 02x because two characters per byte for 1 is already 01. i was working on the todo in the function that changed and had make some test cases for the old padding behavior. They are failing now which is correct as rob explained (since they should be element wise) but their output also reveal that no padding is applied anymore regardless if it should per element or not.
If there should be be per element padding we need to amend the loop to add 0 and white space padding and i guess we also need to treat strings and byte slices differently in respect to padding in the loop or an extra function. Created a new issue. As for strings something more similar to the old padding application might need to be restored:
|
adding to the above - not sure if this is another inconsistency if we need to format per element by the rule "For compound operands such as slices and structs, the format applies to the elements of each operand, recursively, not to the operand as a whole.": currently: but if the format is applied per element should the ' ' mean we need to make a space for the sign? like currently with normal two digit numbers: and the same question can be asked for the # option. To me these two statements cant hold at the same time for slices of bytes:
If 1) then {"%x", []byte{1, 2, 3}, "[1 2 3]"}, |
Reverting this change. An empty slice or empty string printed with padding should show the padding. I will adjust the documentation to make this clear. |
CL https://golang.org/cl/11600 mentions this issue. |
https://play.golang.org/p/S51xT7K4Au
package main
import "fmt"
func main() {
fmt.Printf("% 02x\n", []byte{0})
fmt.Printf("% 02x\n", []byte{})
}
prints 00.
The text was updated successfully, but these errors were encountered: