Jim
Jim

Reputation: 4425

String format and vararg in kotlin

I have the following method

fun formatMessages(indicators: IntArray): CharSequence {
    return context.getString(R.string.foo, indicators)
}

And the string is:

<string name="foo">$1%d - $2%d range of difference</string>

I get a complaint from Android Studio that:
Wrong argument count, format string requires 2 but format call supplies 1

What I am really trying to accomplish is to be able to pass to such a formatMessages any number of indicators (1,2,3..) and the proper string would be selected/displayed.

Upvotes: 2

Views: 2818

Answers (3)

ucMax
ucMax

Reputation: 5476

Feb 2024
Unfortunately, Kotlin's String.format function doesn't directly accept vararg parameters. We have to pass the arguments separately.

But, there is way to achieve the desired outcome, format2 function, convert the vararg argument to an Array and then pass it to String.format :

fun String.Companion.format2(format: String, vararg formatArgs: Any?): String {
    val arguments = arrayOfNulls<Any?>(formatArgs.size)
    formatArgs.copyInto(arguments)
    return String.format(format, *arguments)
}

Upvotes: 0

Alexey Romanov
Alexey Romanov

Reputation: 170831

When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *):

fun formatMessages(indicators: Array<Object>): CharSequence {
    return context.getString(R.string.foo, *indicators)
}

If you need indicators to have type IntArray, you'll have to convert it:

fun formatMessages(indicators: IntArray): CharSequence {
    return context.getString(R.string.foo, *(Array<Object>(indicators.size) { indicators[it] }))
}

Upvotes: 0

noahutz
noahutz

Reputation: 1217

Modify your function to this:

fun formatMessages(indicators: IntArray): CharSequence {
    return context.getString(R.string.foo, indicators[0], indicators[1])
}

But of course you need a proper checking that indicators length is at least 2 so it will not crash.

Reason for this is getString(int resId, Object... formatArgs) runtime will fail because it expects 2 parameters from what is defined in the string resource.

Upvotes: 1

Related Questions