HelloCW
HelloCW

Reputation: 2255

Why does a lambda expression need a explicity return in Android Kotlin?

I'm learning Room with the sample code RoomWordsSample at https://github.com/googlecodelabs/android-room-with-a-view/tree/kotlin.

The Code A is from WordRoomDatabase.kt

1: I can't understand why the author need to add the code INSTANCE = instance, so I remove it and Code B works well, can you tell me why?

2: In my mind, the latest expression in a lambda expression will return result, the val instance = Room.databaseBuilder( ... is latest expression in Code C, but Code C cann't pass compile, why?

Code A

@Database(entities = [Word::class], version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao

    companion object {
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(
                context: Context,
                scope: CoroutineScope
        ): WordRoomDatabase {           
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java,
                        "word_database"
                )
                        .addCallback(WordDatabaseCallback(scope))
                        .build()

                INSTANCE = instance                
                instance
            }
        }
}

Code B

@Database(entities = [Word::class], version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao

    companion object {
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(
                context: Context,
                scope: CoroutineScope
        ): WordRoomDatabase {           
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java,
                        "word_database"
                )
                        .addCallback(WordDatabaseCallback(scope))
                        .build()                        
                instance
            }
        }
}

Code C

@Database(entities = [Word::class], version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao

    companion object {
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(
                context: Context,
                scope: CoroutineScope
        ): WordRoomDatabase {           
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java,
                        "word_database"
                )
                        .addCallback(WordDatabaseCallback(scope))
                        .build()                       

            }
        }
}

Upvotes: 0

Views: 87

Answers (1)

Yrii Borodkin
Yrii Borodkin

Reputation: 782

Code A is implementation of Singleton pattern. It's aim to have only 1 instance of a class. So, Code A checks if INSTANCE is null (was class instance created or not), and if not, it creates instance of WordRoomDatabase class and assigns it to INSTANCE variable. Subsequent calls to getDatabase will return INSTANCE, and not create new WordRoomDatabase each time.

Code B breaks this pattern, not saving instance to static INSTANCE variable. Code will work, but for each subsequent call to getDatabase new instance of WordRoomDatabase will be created.

Code C not working, because getDatabase method must return WordRoomDatabase instance, but it returns nothing (assignments are not expressions in Kotlin)

Upvotes: 5

Related Questions