Я не понимаю, как блок INSTANCE.let работает в этом коде - PullRequest
0 голосов
/ 02 мая 2020

сейчас я учусь Комната в https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#11

и я не могу понять код

            INSTANCE?.let { database ->
                scope.launch {
                    populateDatabase(database.wordDao())
                }
            }

почему существует блок INSTANCE.let, что отличается что

        override fun onOpen(db: SupportSQLiteDatabase) {
            super.onOpen(db)
            scope.launch {
                populateDatabase(database.wordDao())
            }
        }

это полный код

@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {
    abstract fun wordDao(): WordDao

    private class WordDatabaseCallback(
        private val scope: CoroutineScope
    ) : RoomDatabase.Callback() {

        override fun onOpen(db: SupportSQLiteDatabase) {
            super.onOpen(db)
            INSTANCE?.let { database ->
                scope.launch {
                    populateDatabase(database.wordDao())
                }
            }
        }

        suspend fun populateDatabase(wordDao: WordDao) {
            wordDao.deleteAll()

            wordDao.insert(Word("Hello"))
            wordDao.insert(Word("World!"))
        }
    }

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

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

Ответы [ 2 ]

2 голосов
/ 02 мая 2020

.let { } - функция определения объема. Функции Scoping позволяют нам писать краткий код. Давайте рассмотрим этот маленький код:

INSTANCE: представляет экземпляр вашей базы данных Room.

?: говорит: «если значение не ноль »

scope представляет область действия, в которой работает сопрограмма.

INSTANCE?.let { it -> }: говорит об этом (посмотрите на вопросительный знак выше), если INSTANCE равно , не равно нулю , создайте область, которая предоставляет копию ненулевого INSTANCE. it это просто имя по умолчанию, вы можете присвоить ему любое имя, например переменную.

Итак:

   INSTANCE?.let { database ->  //database (or 'it') is not null
            scope.launch { 
                populateDatabase(database.wordDao()) //Now pre-populate the database.
            }
        }
0 голосов
/ 02 мая 2020

Вообще говоря, этот код

 INSTANCE?.let { database ->
            scope.launch {
                populateDatabase(database.wordDao())
            }
 }

- просто более элегантный способ написать это:

if (INSTANCE != nil) {
     scope.launch {
        populateDatabase(INSTANCE!!.wordDao())
     }
}
...