Home > Enterprise >  Why does line 11 fail?
Why does line 11 fail?

Time:08-13

    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?

https://pl.kotl.in/y62nvnNfa

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 CharArrays 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 Iterables. 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()
  • Related