Lecture Correction

There's a very subtle error in the code, in the previous video.

It doesn't prevent the code from working, but it's definitely something you should avoid doing. Unfortunately, it's a very easy mistake to make.

We've created this document to show you what the error is, and to briefly discuss the implications it has.

First, the code - see if you can spot the mistake

val query = database.rawQuery("SELECT * FROM contacts", null)
query.use {
    while (it.moveToNext()) {
        // Cycle through all records
        with(query) {
            val id = getLong(0)
            val name = getString(1)
            val phone = getInt(2)
            val email = getString(3)
            val result = "ID: $id. Name = $name phone = $phone email = $email"
            Log.d(TAG, "onCreate: reading data $result")
        }
    }
}

The error's on line 5 (around line 42 in the video). Have you spotted it yet?

When you call the use function on a closeable object, a reference to that object is passed in as it. That's discussed in the video, in this casewe're calling use on our query variable.

The reference that you call use on is called the receiver, in case you missed that in the video.

Where the code went wrong, was in referring to the receiver directly, using query instead of it on line 5. The correct code should have been

        with(it) {


The code still works, so is this a problem?

Well, it is a minor problem. In this case, it results in slightly less efficient code.

You can see that, by comparing the JVM bytecode that the Kotlin is compiled into. Don't worry if you don't understand bytecode - who does :-)?

We generated the bytecode for the incorrect and the correct code, and took a screenshot while comparing the 2 sets of bytecode. In the screenshot, the incorrect bytecode is on the left


I'll repeat, don't worry about trying to understand bytecode. What's important here, is that the incorrect code results in a reference to query being pushed onto the stack, then popped off again. That's 2 extra instructions that just aren't necessary.

Obviously, executing unnecessary instructions isn't very efficient.

If you do something like this inside a large loop, those extra instructions could be executed thousands of times.

Android Studio doesn't give any warnings about the incorrect code, at the moment, so it's something to be aware of. When using Kotlin functions such as use or apply, take care not to refer to the receiver inside the code block. Make sure you refer to it, rather than the receiver object that you call the function on.