【问题标题】:Converting to kotlin转换为 kotlin
【发布时间】:2018-07-14 17:33:32
【问题描述】:

我正在关注this tutorial,但现在我想将 WordRepository 类转换为 kotlin。我对 kotlin 非常陌生,所以我尝试使用 this online kotlin converter 并从第一个链接复制粘贴 java WordRepository 类。下面是原始的java代码btw:

public class WordRepository {

   private WordDao mWordDao;
   private LiveData<List<Word>> mAllWords;

   WordRepository(Application application) {
       WordRoomDatabase db = WordRoomDatabase.getDatabase(application);
       mWordDao = db.wordDao();
       mAllWords = mWordDao.getAllWords();
   }

   LiveData<List<Word>> getAllWords() {
       return mAllWords;
   }


   public void insert (Word word) {
       new insertAsyncTask(mWordDao).execute(word);
   }

   private static class insertAsyncTask extends AsyncTask<Word, Void, Void> {

       private WordDao mAsyncTaskDao;

       insertAsyncTask(WordDao dao) {
           mAsyncTaskDao = dao;
       }

       @Override
       protected Void doInBackground(final Word... params) {
           mAsyncTaskDao.insert(params[0]);
           return null;
       }
   }
}

以下是我从在线转换器获得的 kotlin 代码:

class WordRepository internal constructor(application:Application) {
  private val mWordDao:WordDao
  internal val allWords:LiveData<List<Word>>
  init{
    val db = WordRoomDatabase.getDatabase(application)
    mWordDao = db.wordDao()
    allWords = mWordDao.getAllWords()
  }
  fun insert(word:Word) {
    insertAsyncTask(mWordDao).execute(word)
  }
  private class insertAsyncTask internal constructor(dao:WordDao):AsyncTask<Word, Void, Void>() {
    private val mAsyncTaskDao:WordDao
    init{
      mAsyncTaskDao = dao
    }
    protected fun doInBackground(vararg params:Word):Void {
      mAsyncTaskDao.insert(params[0])
      return null
    }
  }
}

请注意,为了使上面的代码工作,我改变了

WordRoomDatabase.getDatabase(application)

WordRoomDatabase.getInstance(application)

因为我也将 WordRoomDatabase 更改为 kotlin,并且它不再具有 getDatabase 功能。这是 WordRoomDatabase 的样子

abstract class WordRoomDatabase: RoomDatabase(){

    companion object {
        private var INSTANCE: WordRoomDatabase? = null

        fun getInstance(context: Context): WordRoomDatabase? {
            if (INSTANCE == null){
                synchronized(WordRoomDatabase::class){
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            WordRoomDatabase::class.java, "sps.db")
                            .build()
                }
            }
            return INSTANCE
        }

        fun destroyInstance(){
            INSTANCE == null
        }
    }
}

但是,代码不起作用,特别是这部分:

mWordDao = db.wordDao();

显示错误

只有安全 (?.) 或非空断言 (!!.) 调用才允许在 AppDatabase 类型的可空接收器?

【问题讨论】:

  • @JoeC 我尝试按照您提供的链接中的解决方案进行操作,但随后显示错误“类型不匹配。需要wordDao,找到wordDao了吗?
  • 我的建议是避免以这种方式转换代码,这在学习 kotlin 时会有所帮助,并且您已经知道 java 但它不是解决方案,学习 kotlin 然后重写它。
  • WordRoomDatabase.getDatabase() 返回什么?它是否返回AppDatabase?还是返回AppDatabase?
  • 为了帮助您,问题是 Java 不提供空安全类型,而 kotlin 提供,正如您所见,您有 WordRoomDatabase?,这意味着 INSTANCE 可以为空, kotlin 不允许在不检查值是否为空的情况下调用此类类型的方法。

标签: kotlin


【解决方案1】:

这里的问题是您在调用 WordRoomDatabase.getInstance() 时返回一个 可为空 实例(问题标记类型),因为它是签名。

您可以将getInstance 更改为:

    fun getInstance(context: Context): WordRoomDatabase {
        if (INSTANCE == null){
            synchronized(WordRoomDatabase::class){
                INSTANCE = when you call [https://kotlinlang.org/docs/reference/null-safety.html#safe-calls](https://kotlinlang.org/docs/reference/null-safety.html#safe-calls)Room.databaseBuilder(context.getApplicationContext(),
                        WordRoomDatabase::class.java, "sps.db")
                        .build()
            }
        }
        return INSTANCE as WordRoomDatabase
    }

为了进一步了解可空类型和安全调用,这里有一些有用的链接:

https://kotlinlang.org/docs/reference/null-safety.html#safe-calls

https://www.callicoder.com/kotlin-nullable-types-null-safety/

【讨论】:

  • 谢谢。但是我一直在想,像原始复制粘贴的代码一样,拥有 getInstance 返回 null 的能力有什么好处或坏处?
  • 主要优点是您不必检查 getInstance 是否为空,这意味着您将减少很多相关的样板代码。谢谢你可以保证你永远不会得到一个空实例,因为你总是在返回之前对其进行初始化。作为缺点,我目前看不到任何缺点
  • 我已经用两个链接更新了帖子,应该有助于更好地理解。
猜你喜欢
  • 2018-11-26
  • 1970-01-01
  • 2023-01-29
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多