I'm trying to understand pluralization in Go. The example from the docs https://godoc.org/golang.org/x/text/message/catalog#hdr-String_interpolation does not work. The method plural.Select
does not event exist. It should be plural.Selectf
. Note the f
at the end.
message.Set(language.English, "You are %d minute(s) late.",
catalog.Var("minutes", plural.Selectf(1, "one", "minute")),
catalog.String("You are %d ${minutes} late."))
p := message.NewPrinter(language.English)
p.Printf("You are %d minute(s) late.", 5)
I found another tutorial here https://phraseapp.com/blog/posts/internationalization-i18n-go/. This code works fine
message.Set(language.English, "You have %d problem",
catalog.Var("minutes", plural.Selectf(1, "%d", "one", "minute", "other", "minutes")),
catalog.String("You are %d ${minutes} late."))
printer := message.NewPrinter(language.English)
printer.Printf("You have %d problem", 1)
printer.Println()
printer.Printf("You have %d problem", 3)
printer.Println()
// result
// You are 1 minute late.
// You are 3 minutes late.
Both examples use the advanced string interpolation. Now I'm trying to understand plural.Selectf
. What is the first argument 1
doing? Why do I need the second argument %d
? I think I understand the rest
"one" : "minute"
"other": "minutes"
I also saw %[1]d
in catalog.String
. What does this do?
Thanks a lot! I'm super confused right now.
Here you go!
The first argument of plural.Selectf
is an int
. So it can be any valid integer.
The second argument is a string
. It should be a format verb i.e %d
or %s
or %f
The third argument is an empty interface, could receive any type i.e string, struct, catalog.Message, ..
Let's take this example,
func main() {
var (
msg = plural.Selectf(2, "%d",
"=10", "%[1]d task and %[2]d processes remaining!", // interface 1
"=1", "%[1]d task and %[2]d processes", // interface 2
"other", "%d tasks and %d processes!" // interface 3
)
key = "%d task - %d process"
tag = "en"
)
lTag := language.MustParse(tag)
message.Set(lTag, key, msg)
p := message.NewPrinter(language.English)
p.Printf("%d task - %d process", 1, 10)
}
Here we have created a NewPrinter
with language English and set the translation messages with the key %d task(s) remaining!
for tag en
(short code for English language).
When p.Printf("%d task - %d process", 1, 3)
line executes, the translation mechanism takes the first argument(format specifier) i.e %d task - %d process
and checks for the message by comparing with key we set in for en
tag. If the key is found, then it processes the message i.e msg
.
Here the Selectf
s first argument says that take nth
(i.e 2nd in our case) format verb's value from Printf
(i.e 10 in the second value for %d) and compare with selector of cases i.e =10
in the case 1 (interface 1). If the comparison is success then returns the processed value i.e 1 task and 10 processes
in case 1.
If the Printf
receives values for 2nd %d other than 1 & 10 then it would return the value from case 3 (interface 3)
And,
The %[n]d
could be used like,
fmt.Printf("%[2]d %[1]d\n", 11, 22)
and it prints 22 11
.
Hope, this helps you.