假设一个Android项目中有两个按钮的XML:
<layout>
<data>
<variable name="viewModel" type="com.package.package.UploadPhotoViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
android:padding="10dp">
<com.zoosk.zoosk.ui.widgets.ProgressButton
android:id="@+id/progressButtonChooseFromLibrary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.choosePhotoText}"
android:onClick="@{viewModel::choosePhotoButtonClick}"
android:visibility="@{viewModel.choosePhotoVisibility}" />
<com.zoosk.zoosk.ui.widgets.ProgressButton
android:id="@+id/progressButtonTakePhoto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.takePhotoText}"
android:onClick="@{viewModel::takePhotoButtonClick}"
android:visibility="@{viewModel.takePhotoVisibility}" />
</LinearLayout>
</layout>
以及随附的ViewModel:
class UploadPhotoViewModel(resources: Resources) {
var onChoosePhotoButtonClicked: ((View) -> Unit)? = null
var onTakePhotoButtonClicked: ((View) -> Unit)? = null
fun choosePhotoButtonClick(v: View) {
onChoosePhotoButtonClicked?.invoke(v)
}
fun takePhotoButtonClick(v: View) = onTakePhotoButtonClicked?.invoke(v)
}
特别注意choosePhotoButtonClick
和takePhotoButtonClick
的声明方式。
在构建此项目时,Android的数据绑定将在choosePhotoButtonClick
上正常工作,但会在takePhotoButtonClick
上引发错误,表示没有与预期参考签名匹配的方法。假设这些方法是在幕后以相同的方式创建的,那么这种情况就不会发生,因为一定会有区别。
这两种声明语法到底有什么区别? official Kotlin documentation没有提及任何功能,只是提及它可以作为声明该方法的另一种方式。
答案 0 :(得分:0)
如果使用花括号而不指定返回类型,则您的函数将隐式调整Unit
(这是void
的Kotlin),因此您的方法是
fun choosePhotoButtonClick(v: View) {
onChoosePhotoButtonClicked?.invoke(v)
}
具有以下签名:
fun choosePhotoButtonClick(v: View) : Unit
(IDE将提示返回类型“ Unit”是多余的,可以忽略)。
但是使用等号来简化函数可以推断右侧表达式的返回类型,例如:
fun itemCount() = items.size
将推断出Int
的返回类型,因此其签名为:
fun itemCount() : Int
在您的情况下:
fun takePhotoButtonClick(v: View) = onTakePhotoButtonClicked?.invoke(v)
函数可以在null
为空时返回onTakePhotoButtonClicked
或该方法的返回值(Unit
),这意味着您的takePhotoButtonClick
签名为:
fun takePhotoButtonClick(v: View) : Unit?
(OP)直接解决问题:
fun takePhotoButtonClick(v: View) = onTakePhotoButtonClicked?.invoke(v) ?: Unit
可以被认为比花括号版本的可读性差,但这意味着单元的返回类型而不是单元吗?并将通过数据绑定正确地拾取。