kotlin延迟初始化属性不能在init块中修改

moh*_*sen 2 android constructor kotlin

我的类中有一些属性是延迟初始化的。我希望它们是不可变的,这就是为什么我不使用它们lateinit,并且我不希望它们可以为空,所以我认为懒惰是最好的选择。

init我的类的块中,我想修改其中一个属性,但它给了我编译错误:Variable 'mLstQuestions' must be initialized
我知道惰性属性在使用后立即初始化,那么为什么会发生这种情况呢?我怎样才能解决这个问题?什么是更好的方法?

如果我创建一个函数Initialize()并在该函数中修改它。完全没问题,我可以在 init 块中调用它。为什么呢?这工作正常吗?有什么不同?如果在块中禁止执行类似的操作init,那么函数调用是否也应该被禁止?

这是我的代码:

class CharacterListView(
    inflater: LayoutInflater,
    parent: ViewGroup
) {
    init {
        mLstQuestions.adapter = mQuestionsListAdapter
        // error : Variable 'mLstQuestions' must be initialized
        // error : Variable 'mQuestionsListAdapter' must be initialized
    }
    
    private val mLstQuestions by lazy { findViewById<RecyclerView>(R.id.char_list) }
    private val mQuestionsListAdapter by lazy { QuestionsListAdapter(getContext(), this) }
    private val mRootView by lazy { inflater.inflate(R.layout.activity_main, parent, false) }
...
}
Run Code Online (Sandbox Code Playgroud)

这是带有初始化函数的代码:

class CharacterListView(
    inflater: LayoutInflater,
    parent: ViewGroup
) {
    init { initialize() } // no errors!

    private fun initialize() {
        mLstQuestions?.adapter = mQuestionsListAdapter
    }

    private val mLstQuestions by lazy { findViewById<RecyclerView>(R.id.char_list) }
    private val mQuestionsListAdapter by lazy { QuestionsListAdapter(getContext(), this) }
    private val mRootView by lazy { inflater.inflate(R.layout.activity_main, parent, false) }
...
}
Run Code Online (Sandbox Code Playgroud)

Sha*_*T D 5

init{ }请尝试在declaration变量之后定义块。

class CharacterListView(
    inflater: LayoutInflater,
    parent: ViewGroup
) { 
    private val mLstQuestions by lazy { findViewById<RecyclerView>(R.id.char_list) }
    private val mQuestionsListAdapter by lazy { QuestionsListAdapter(getContext(), this) }
    private val mRootView by lazy { inflater.inflate(R.layout.activity_main, parent, false) }

init {
        mLstQuestions.adapter = mQuestionsListAdapter
    }
}
Run Code Online (Sandbox Code Playgroud)