Having trouble passing a value in a Kotlin function. The variable being convert:(String)->R

Viewed 36

I have some code here that reads a file and converts it to a list of a type depending what is being passed to the function. The code for this function looks like so.

fun <R> readFile(path:String,convert:(String)->R): List<R> {
    val reader = BufferedReader(FileReader(File(path)))
    var line = reader.readLine()
    val result = mutableListOf<R>()
    while(line!=null) {
        result.add(convert(line))
        line = reader.readLine()
    }
    reader.close()
    return result.toList()
}

The problem I have is that I am unsure sure what to pass into the variable convert. I am trying to return back a list of Person objects back. Below is the code I tried myself to hit the function readFile

val listOfPerson = readFile("path/person.txt","Person")

With this I'm getting an error with my Type. Intellij is flagging "Required (String) -> ???"

1 Answers

The type (String) -> R is a function type. It represents a function that takes a String as argument and returns R (which is generic and can be different on every call to readFile()).

In order to call readFile(), you need to pass a String and a function:

readFile("path/person.txt") { line -> /* whatever you need */}

Note that in Kotlin, the { line -> ...} is a lambda expression, i.e. a function literal. This particular lambda expression represents a function that takes the argument line and does whatever is in the body.

Lambda expressions can be passed out of the parentheses of the function call, but it's still an argument to the function. The above code is equivalent to:

readFile("path/person.txt", { line -> /* whatever you need */})

In your specific case, the convert argument is a conversion function, so you need to provide some code that converts the line: String argument into whatever R type you need in the output list.

If you just want a list of the lines as strings (without conversion) you can simply provide the identity function:

readFile("path/person.txt") { line -> line }

Or in short:

readFile("path/person.txt") { it }

it is an implicit argument (a shortcut) for lambda expressions that represent functions with only 1 argument, which is the case here.

Related