为什么在Kotlin可以更改val属性?

时间:2018-04-25 08:51:57

标签: android kotlin

代码B是一个定制的RecyclerView apater,带有单选按钮。

mCustomAdapter在代码A中的有趣方法A()和有趣的方法B()中都被更改,因此get () = mCustomAdapter.getSelectedIndex()的引用也被更改,这意味着val属性mySelectedIndex从不同的地址获取值。

在我看来,val属性无法更改,为什么应用程序不会导致错误?

代码A

private lateinit var mCustomAdapter: CustomAdapter

private val mySelectedIndex get () = mCustomAdapter.getSelectedIndex()

private fun methodA(){
  mCustomAdapter= CustomAdapter(allListA)
  mRecyclerView.adapter= mCustomAdapter
  backup(mySelectedIndex)
}


private fun methodB(){
  mCustomAdapter= CustomAdapter(allListB)
  mRecyclerView.adapter= mCustomAdapter
  restore(mySelectedIndex) 
}

代码B

class CustomAdapter (val backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    val noRecord=-1
    private var mSelectedIndex = noRecord

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview, parent, false)
        return ViewHolder(v)
    }

    fun getSelectedIndex():Int{
        return  mSelectedIndex
    }

    fun setSelectedIndex(index:Int){
        if (index in 0..(backupItemList.size-1) ){
            mSelectedIndex=index
        }
        notifyDataSetChanged();
    }

    override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
        holder.bindItems(backupItemList[position])
    }

    override fun getItemCount(): Int {
        return backupItemList.size
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bindItems(aMSetting: MSetting) {          

            itemView.radioButton.setOnClickListener {
                mSelectedIndex=adapterPosition
                notifyDataSetChanged();
            }

            if(adapterPosition == 0 && mSelectedIndex == noRecord) {            
                itemView.radioButton.isChecked = true
                mSelectedIndex=adapterPosition
            }
            else {
                itemView.radioButton.isChecked =(adapterPosition == mSelectedIndex)
            }
        }

    }

}

已修改

我认为Code DD和Code EE可以产生同样的效果,对吗?

代码DD

var aImpl = 0
val a: Int get() = aImpl

fun seta(){
    aImpl=5
}

代码EE

var b:Int=0

fun setb(){
    b=5
}

3 个答案:

答案 0 :(得分:4)

  

在我看来,val属性无法更改,为什么app不会导致错误?

你必须调整自己的直觉。

在Kotlin中,val表示“只读属性”,而不是“不可变属性”。只有没有自定义getter的val才能被认为是不可变的。

答案 1 :(得分:1)

val属性每次调用时都会返回不同的值:

private var aImpl = 0
val a: Int get() = aImpl++

由于mCustomAdapter.getSelectedIndex()的返回值正在发生变化,mySelectedIndex显然正在发生变化。

答案 2 :(得分:1)

关于属性时,关键字val表示该属性没有setter,这意味着您不能使用赋值运算符=。这并不意味着返回的值必须随着时间的推移而保持不变。