Go vet Sprinf checking number of arguments

48 Views Asked by At

I’ve found an interesting behavior of go vet with Sprintf which I would not expect (it’s inside the lint check).

Could you explain me why go vet is not throwing a violation in the second numbered case (case 2)? I’d expect it should also cover this case as developer might forget to update the formatting string. Or, at least to have a possibility to turn this kind of check on by configuration.

Thanks for explanation.

case 1: For this check, I get a violation:

fmt.Sprintf("%[1]s%[2]s", "foo")

case 2: When I pass more arguments into Sprintf than expected, everything is fine from go vet perspective:

fmt.Sprintf("%[1]s", "foo", "bar")

case 3: When I don't use numbered arguments in this case, I get a violation from go vet

fmt.Sprintf("%s", "foo", "bar")
1

There are 1 best solutions below

0
On

Numbered format parameters main use case is to separate what the format string uses (in whatever order) from the arguments.

Think of translations where you might want to switch the format string from "%[1]s hits %[2]s" to "%[2]s got hit by %[1]s". For this type it often is necessary to drop arguments (because you do not need them in the output; think of "%[2] got hit"). Numbered arguments allow to repeat stuff like in "%[1]s foo %[1]s bar %[1]s".

So numbered arguments are about re-ordering, duplicating and dropping arguments. If go vet would warn about unused arguments this main use case of numbered arguments would not work.

Case 1: is a bug because the fmt string requires two arguments.

Case 3: One, single argument required, two given, no intention to resort/regroup/duplicate

Case 2: format string makes clear it likes to re-order, duplicate or drop arguments by using numbered arguments. More arguments given than currently needed: Fine.