Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 普通和单表达式函数定义之间的差异_Android_Kotlin_Android Databinding - Fatal编程技术网

Android 普通和单表达式函数定义之间的差异

Android 普通和单表达式函数定义之间的差异,android,kotlin,android-databinding,Android,Kotlin,Android Databinding,假设有一个Android项目,其中有两个按钮的XML: <layout> <data> <variable name="viewModel" type="com.package.package.UploadPhotoViewModel" /> </data> <LinearLayout android:layout_width="match_parent" androi

假设有一个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>
特别注意
choosePhotoButtonClick
takePhotoButtonClick
的声明方式之间的差异

构建此项目时,Android的数据绑定将在
choosePhotoButtonClick
中正常工作,但在
takePhotoButtonClick
中抛出错误,表示没有与预期引用签名匹配的方法。假设这些方法在引擎盖下以相同的方式创建,这不应该发生,唉,肯定有一些不同


这两个声明语法到底有什么区别?没有提到任何函数,只是它可以作为声明该方法的附加方式。

如果使用大括号而不指定返回类型,则函数将隐式重新调整
单元(这是Kotlin for
void
),因此您的方法:

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) : Unit?
在您的情况下:

fun takePhotoButtonClick(v: View) = onTakePhotoButtonClicked?.invoke(v)
函数可以在
onTakePhotoButtonClicked
为null时返回
null
,或者返回该方法的值(
Unit
),这意味着您的
takePhotoButtonClick
签名为:

fun itemCount() : Int
fun takePhotoButtonClick(v: View) : Unit?
(OP)问题的直接解决方案:

fun takePhotoButtonClick(v: View) = onTakePhotoButtonClicked?.invoke(v) ?: Unit

可以认为它的可读性不如大括号版本,但这意味着返回类型是Unit而不是Unit?并且将通过数据绑定正确拾取。

对于
onGuidelinesLinkClicked
调用表示歉意,其目的是函数将各自调用各自的lambda,但您正确地假设签名是相同的。尽管很有趣。我知道
单元
类型是Kotlin for
void
,但我没有想到返回类型是
单元
。也许可以通过在末尾添加
?:Unit
来解决这个问题,以确保返回不是可选的?不管怎样,我都会试试。@SpyisSandvich
Unit
被用来代替
void
,但是它是,所以可空类型
Unit?
是有效的。追加
?:Unit
应该是一个有效的解决方案,但我个人认为使用大括号更具可读性。追加
?:
在这种情况下确实有效。我选择使用它,因为整个想法是将onClick完全连接到传递到ViewModel的功能,它可能存在,也可能不存在,只需要几行就可以了。但是,如果我要对ViewModel中的功能做任何其他事情,那么我肯定会喜欢花括号版本。