How do I make method param mutable in Kotlin?

Mutable parameters are not supported in Kotlin.

I would like to refer you to this discussion in kotlinlang.org


There are two issues here.

First, you are mistakenly assuming that modifying view in Java does anything outside of the current function scope. It does not. You setting that parameter to a new value affects nothing outside of the local function scope.

View getView(int i, View view, ViewGroup parent) {
   // modify view here does nothing to the original caller reference to view
   // but returning a view does do something
}

Next, in Kotlin all parameters are final (JVM modifier, also same as final modifier in Java). The Kotlin if statement version of this code would be:

fun getView(i: Int, view: View?, parent: ViewGroup): View {
   return if (view == null) {
       val tempView = View.inflate(context, R.layout.item_spinner, parent)
       tempView.tag(Holder(tempView))
       tempView
   } else { 
       (view.tag as Holder).title.text = getItem(i)
       view
   }
}

or avoiding the new local variable:

fun getView(i: Int, view: View?, parent: ViewGroup): View {
   return if (view == null) {
       View.inflate(context, R.layout.item_spinner, parent).apply {
           tag(Holder(this)) // this is now the new view
       }
   } else { 
       view.apply { (tag as Holder).title.text = getItem(i) }
   }
}

or

fun getView(i: Int, view: View?, parent: ViewGroup): View {
   if (view == null) {
       val tempView = View.inflate(context, R.layout.item_spinner, parent)
       tempView.tag(Holder(tempView))
       return tempView
   } 

   (view.tag as Holder).title.text = getItem(i)
   return view
}

or using the ?. and ?: null operators combined with apply():

fun getView(i: Int, view: View?, parent: ViewGroup): View {
    return view?.apply { 
                (tag as Holder).title.text = getItem(i) 
           } ?: View.inflate(context, R.layout.item_spinner, parent).apply {
                     tag(Holder(this))
                }
}

And there are another 10 variations, but you can experiment to see what you like.

It is considered less-than-a-good practice (but allowed) to shadow variables by using the same name, that is why it is a compiler warning. And why you see a change in the variable name above from view to tempView


There's a dirty but useful way to achieve that.

fun a(b: Int) {
   var b = b
   b++ // this compiles
}

Tags:

Android

Kotlin