1 fun main() {
2 val listOfWords = arrayOf("one", "two", "three")
3
4 // Test1
5 val test1 = listOfWords[1].toCharArray()
6 test1.shuffle()
7 String(test1)
8
9 // Test2
10 val test2 = listOfWords[1].toCharArray().shuffle()
11 String(test2) // Problem here: String() doesn't like test2
12 }
Why does line 11 fail?
Or, maybe a better question is: why is String() happy with test1, on line 7?
CodePudding user response:
This is long but I hope it explains a few things, and helps you work out how to solve these errors when they come up!
Here's the error you get:
None of the following functions can be called with the arguments supplied:
public inline fun String(stringBuffer: StringBuffer): String defined in kotlin.text
public inline fun String(stringBuilder: StringBuilder): String defined in kotlin.text
public inline fun String(bytes: ByteArray): String defined in kotlin.text
public inline fun String(chars: CharArray): String defined in kotlin.text
Those are the possible one-argument calls to String()
and it's saying the arguments you're supplying (just test2
in this case) don't match any of those signatures. It's the wrong type.
Since you're working with CharArray
s and that's one of the accepted arguments, you probably think test2
is one, but it's not. That's what you need to investigate. Like you say, test1
is fine - so what's the difference here? What's different about the way you're creating those two values, that they'd end up being different types?
The difference is with test2
you're calling shuffle()
on it. You probably expected that to return the newly shuffled array, but since test2
apparently isn't a CharArray
, then seems like something else is going on, right? Better check what shuffle
actually does:
fun CharArray.shuffle()
Randomly shuffles elements in this array in-place.
Two things there. One - it says it shuffles in-place meaning it doesn't return a new copy of the array with the contents shuffled, it just moves things around in the given array object. You see this a lot, e.g. sort
(in-place) vs sorted
(produces a new sorted copy, the original is untouched) and it's important to be aware that there are often two versions of this kind of thing!
The second thing is that the function signature up there has no return type. So it's really
fun CharArray.shuffle(): Unit
Which is another sign that it doesn't produce anything, it just modifies something. And it means that it doesn't return a value (except Unit
, which really represents no value like void
in Java). So when you create test2
, calling shuffle
on an array, the result is Unit
, nothing, nada. And that's why you can't pass it to the String
constructor.
There actually is a shuffled()
function, but it's only for Iterable
s. So you could do this:
// converting to a `List` so you can run `shuffled` on it
val test2 = listOfWords[1].toCharArray().toList().shuffled().toCharArray()
but you might as well skip that intermediate array:
val test2 = listOfWords[1].toList().shuffled().toCharArray()