我怎样才能在 Kotlin 中简化这个单例?
How can I make this singleton simpler in Kotlin?
如何在 Kotlin 中简化这个用于 Android 房间数据库初始化的单例?
@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
INSTANCE = Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
}
return INSTANCE!!
}
fun destroyInstance() {
INSTANCE = null
}
}
}
您可以使用数组文字 ([]
) 而不是 arrayOf
,并且可以使用 elvis 运算符进行空值检查。参见 。
@Database(entities = [Book::class, User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
return INSTANCE!!
}
fun destroyInstance() {
INSTANCE = null
}
}
}
因为您需要实例,所以您必须将它保存在某个地方,使用 companion object
对我来说似乎是一个合理的解决方案。
如果你不想在 AppDatabase
中保存实例,你也可以使用一个对象(在 Kotlin 中是一个单例)。
object AppDatabaseProvider {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
// ...
}
fun destroyInstance() {
INSTANCE = null
}
}
这些都是在 Kotlin 中处理静态数据的选项,但你不会得到比这短得多的选项。
也许会提前,试试看
@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
return INSTANCE ?: Room.inMemoryDatabaseBuilder(context, this).build()
}
fun destroyInstance() {
INSTANCE = null
}
}
}
您的解决方案基本上没有问题。
使用数组文字是一种选择,正如@Willi Mentzel 所指出的那样,如果您喜欢它的外观,它会使您的代码更短一些。
但是,这段获取单例实例的代码是错误的:
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context) = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
getInMemoryDatabase
函数从不 分配 一个值给 INSTANCE
,这意味着它永远是 null
,并且每次函数都是调用时,将评估并返回 Elvis 运算符的右侧。这意味着每次都有一个新实例 - 而不是拥有一个单例,您只是使用此代码创建一个工厂。
您可以使用 Elvis 运算符稍微缩短您的原始代码:
fun getInMemoryDatabase(context: Context): AppDatabase {
INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
return INSTANCE!!
}
不过,这会在第一次调用后对自己进行额外的 INSTANCE
赋值,我认为保存这两行可能不值得,因为你的原始代码只有一个常规空检查比这更容易阅读。
如何在 Kotlin 中简化这个用于 Android 房间数据库初始化的单例?
@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
INSTANCE = Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
}
return INSTANCE!!
}
fun destroyInstance() {
INSTANCE = null
}
}
}
您可以使用数组文字 ([]
) 而不是 arrayOf
,并且可以使用 elvis 运算符进行空值检查。参见
@Database(entities = [Book::class, User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
return INSTANCE!!
}
fun destroyInstance() {
INSTANCE = null
}
}
}
因为您需要实例,所以您必须将它保存在某个地方,使用 companion object
对我来说似乎是一个合理的解决方案。
如果你不想在 AppDatabase
中保存实例,你也可以使用一个对象(在 Kotlin 中是一个单例)。
object AppDatabaseProvider {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
// ...
}
fun destroyInstance() {
INSTANCE = null
}
}
这些都是在 Kotlin 中处理静态数据的选项,但你不会得到比这短得多的选项。
也许会提前,试试看
@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun bookModel() : BookDao
abstract fun userModel() : UserDao
companion object {
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context): AppDatabase {
return INSTANCE ?: Room.inMemoryDatabaseBuilder(context, this).build()
}
fun destroyInstance() {
INSTANCE = null
}
}
}
您的解决方案基本上没有问题。
使用数组文字是一种选择,正如@Willi Mentzel 所指出的那样,如果您喜欢它的外观,它会使您的代码更短一些。
但是,这段获取单例实例的代码是错误的:
private var INSTANCE: AppDatabase? = null
fun getInMemoryDatabase(context: Context) = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
getInMemoryDatabase
函数从不 分配 一个值给 INSTANCE
,这意味着它永远是 null
,并且每次函数都是调用时,将评估并返回 Elvis 运算符的右侧。这意味着每次都有一个新实例 - 而不是拥有一个单例,您只是使用此代码创建一个工厂。
您可以使用 Elvis 运算符稍微缩短您的原始代码:
fun getInMemoryDatabase(context: Context): AppDatabase {
INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
return INSTANCE!!
}
不过,这会在第一次调用后对自己进行额外的 INSTANCE
赋值,我认为保存这两行可能不值得,因为你的原始代码只有一个常规空检查比这更容易阅读。