51

Here is my program.

package main

import (
    "errors"
    "fmt"
)

func main() {
    a := -1
    err := assertPositive(a)
    fmt.Printf("error: %s; int: %d\n", err, a)
    fmt.Printf("error: %v; int: %d\n", err, a)
}

func assertPositive(a int) error {
    if a <= 0 {
        return errors.New("Assertion failure")
    }
    return nil
}

Here is the output.

error: Assertion failure; int: -1
error: Assertion failure; int: -1

In this program, it makes no difference whether I use %s or %v to print the error object.

I have two questions.

  1. Is there any scenario while printing errors where it would make a difference for %s and %v?
  2. What is the correct format specifier to use in this case?
3
  • 1
    Use %s (but please look up what %v and %s do in the package description of fmt). Commented May 10, 2017 at 9:06
  • 3
    @Volker I know what %v and %s does. I would like to understand why you recommend %s for error objects. Can you share the rationale please? Commented May 10, 2017 at 13:54
  • 3
    Less indirection. What gets printed is the output of the Error() method and that's a string: Clearer. Commented May 10, 2017 at 14:26

2 Answers 2

52

According to docs:

%v  the value in a default format
...
%s  the uninterpreted bytes of the string or slice

Also, more information about error:

The error type is an interface type. An error variable represents any value that can describe itself as a string.

So, treat it as %s.

Sign up to request clarification or add additional context in comments.

4 Comments

The only thing that I'd say is perhaps confusing about this is that the Golang team uses %v in their blogs: blog.golang.org/error-handling-and-go. Otherwise I think it's probably okay to just use %s as well.
Also more discussion in this issue here: github.com/golang/go/issues/29934, which is somewhat relevant
Is it worth mentioning the special handling for format strings ending in ": %s" followed by an error? That's very non-intuitive (if it was retained in the language; I'm not sure.) See @NathanLutterman's citation.
@Nathan Lutterman %v properly formats <nil> errors. %s outputs something like this when the error is nil: %!s(<nil>)
-2

%w is what is the correct format specifier according to https://pkg.go.dev/fmt#Errorf

1 Comment

It's the wrapping directive. You can't use it in fmt.Println or fmt.Printf. It servers a different purpose rather than simply formatting

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.