I would like to implement a version of errors.New
that accepts the same parameters as fmt.Sprintf
To do so I wrote the following function:
func NewError(format string, a ...interface{}) error {
return errors.New(fmt.Sprintf(format, a))
}
However, a
becomes a single array parameter inside NewError()
thereby causing Sprintf()
to fill out just a single parameter in the format string. How can I force a
to be interpreted as a variable number of arguments?
The easiest way to create custom errors in Golang is to use the New() function which is present in the errors module of Golang.
Use %w instead of %v or %s : As of Go 1.13 (or earlier if you use golang.org/x/xerrors), you can use the %w verb, only for error values, which wraps the error such that it can later be unwrapped with errors. Unwrap , and so that it can be considered with errors.Is and errors.As .
In Go 1.13, though, Go added support for wrapping and unwrapping errors as part of the standard library by adding the errors. Unwrap function and the %w verb for the fmt. Errorf function. In this section, you'll update your program to use the %w verb to wrap errors with more information, and you'll then use errors.
To use this function, you must import the fmt package in your file and access the Errorf function within, using the . notation: fmt. Errorf . Here, Errorf is the actual function, while fmt is the Go package that stores the definition of this function.
fmt.Errorf
already does what you are trying to do. Looking at its source, you can see what went wrong:
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
func Errorf(format string, a ...interface{}) error {
return errors.New(Sprintf(format, a...))
}
Note your code is missing the ...
after a
. From the spec:
Passing arguments to ... parameters
If the final argument is assignable to a slice type
[]T
, it may be passed unchanged as the value for a...T
parameter if the argument is followed by...
. In this case no new slice is created.Given the slice
s
and calls := []string{"James", "Jasmine"} Greeting("goodbye:", s...)
within
Greeting
, who will have the same value ass
with the same underlying array.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With