如何在Kotlin中使方法参数可变?

ole*_*men 3 android kotlin

我正在实施一个SpinnerAdapterAndroid项目。所以我必须重写getView(i: Int, convertView: View, parent: ViewGroup)方法。convertView为了重用现有视图并减少内存使用和GC发生,此处也是如此。因此,如果是这样,null我必须创建视图并使用已经创建的视图。

所以实际上我必须写这样的东西(由Google官方推荐):

if (view == null) {
    view = View.inflate(context, R.layout.item_spinner, parent)
    view.tag(Holder(view))
} else {
    (view.tag as Holder).title.text = getItem(i)
}
Run Code Online (Sandbox Code Playgroud)

但是Kotlin不允许写param。我在互联网上发现的是一篇官方博客文章,内容是自2013年2月以来不可能。

所以我想知道是否有任何解决方法?

ice*_*000 6

有一种肮脏但有用的方法可以实现这一目标。

fun a(b: Int) {
   var b = b
   b++ // this compiles
}
Run Code Online (Sandbox Code Playgroud)

  • 似乎不起作用。我不知道这是做什么的,但我认为它除了关闭编译器并修改然后丢弃的局部变量之外什么也没做。 (2认同)

Par*_*Deb 5

Kotlin支持可变参数。

我想让你参考kotlinlang.org 中的这个讨论


Jay*_*ard 5

这里有两个问题。

首先,您错误地认为view在Java中进行修改会执行当前函数范围之外的任何事情。它不是。将该参数设置为新值不会影响本地函数范围。

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
}
Run Code Online (Sandbox Code Playgroud)

接下来,在Kotlin中,所有参数都是final(JVM修饰符,也与finalJava中的修饰符相同)。if此代码的Kotlin 语句版本为:

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
   }
}
Run Code Online (Sandbox Code Playgroud)

或避免使用新的局部变量:

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) }
   }
}
Run Code Online (Sandbox Code Playgroud)

要么

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
}
Run Code Online (Sandbox Code Playgroud)

或结合使用?.和和?:null运算符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))
                }
}
Run Code Online (Sandbox Code Playgroud)

另外还有10种变化,但是您可以尝试看看自己喜欢什么。

通过使用相同的名称来阴影变量是一种不太好的做法(但允许),这就是为什么它是编译器警告。以及为什么您看到上面的变量名称从view变为tempView