我正在try 学习一些Android基础知识,并使用这个UI来在单击时生成随机数:

@Composable
fun DiceWithButton(modifier: Modifier = Modifier) {
    var value by remember { mutableStateOf(1) }
    fun rollNew() {
        value = (1..6).random()
    }
    Column(modifier = blabla) {
        Text(text = value.toString())
        Button(onClick = rollNew) {
            Text("Roll")
        }
    }
}

它无法用消息Type mismatch: inferred type is Unit but () -> Unit was expected构建

但当我将rollNew重写为Lambda时,它工作得很好:

var rollNew = {
    value = (1..6).random()
}

这对来自Python/JavaScript/Golang背景的我来说很困惑,其中任何函数值都可以用()调用.

Kotlin有什么区别?为什么用fun定义rollNew时有Unit类型? 或者Kotlin是否试图在功能时调用rollNew,因此调用Unit

推荐答案

要使用函数声明声明的函数作为函数类型的值,您应该使用callable reference expression,即

Button(onClick = ::rollNew)

仅仅单独编写函数的名称是无效的语法.

这对来自Python/JavaScript/Golang背景的我来说很困惑,其中任何函数值都可以用()调用.

在Kotlin中,rollNew不是"函数值".它是由函数声明的名称,而不是其本身的表达.::rollNew is一个函数值,以及拉姆达表达式和匿名函数声明(这两者统称为function literals).

Kotlin有什么区别?为什么用fun定义rollNew时有Unit类型?或者Kotlin是否试图在功能时调用rollNew,因此调用Unit

rollNew本身根本不是一个表达,所以谈论它的类型是无稽之谈.正如您所猜测的那样,这只是编译器"猜测"您想要调用它.除了无与伦比的类型错误消息之外,您还收到"期望函数调用rowNew()"错误.

啊,那么在Kotlin中,函数不是一等公民,但尤利西斯是一等公民,::是用来将函数转换为Lamanda的?

这是语法和语义的混淆.Lambda表达和可调用引用都是该语言的语法特征.从语义上来说,这两者都代表了"函数"的概念--这些表达的类型是函数类型等.能够传递"函数"并调用它们是使函数成为一流公民的原因,无论您使用什么语法来做到这一点.当然,::并不能将任何东西转化为Aldas.这与Lambda表达的语法完全不同.

作为一个类比,这就像看到val str = Foo产生错误,但val str = "Foo"会编译,并得出"字符串不是一等公民,但字符串字面量是".

话虽如此,但通用函数(具有自由类型参数的函数)确实不是一流公民,但那是另一回事了.

Kotlin相关问答推荐

Android Jetpack编写androidx.compose.oundation.lazy.grid.Items

解决Microronaut中多个可能的Bean候选者冲突

在Kotlin中将String转换为T

Groovy Gradle文件的Kotlin类似功能

在调用父构造函数之前重写类属性

用vararg替换列表的设计弃用警告

Kotlin 获取继承类的默认 hashCode 实现

如何访问嵌套在另一个 map 中的 map 中的值(在 kotlin 中)

当 func 重载时,kotlin 如何确定调用哪个 func?

Kotlin 启动与启动(Dispatchers.Default)

Kotlin 中的as Long和.toLong()有什么区别?

如何将jooq multiset的结果映射到Hashmap(Java Map)?

Kotlin 1.2.21 + SimpleXml 2.3.0 - consume List error (must mark set get method)

为什么我在使用 Jetpack Compose clickable-Modifier 时收到后端内部错误:Exception during IR lowering error?

未在IntelliJ IDEA上运行临时文件

Android Studio 和 Kotlin:Unresolved reference: also

在Kotlin中不带类直接引用枚举实例

Tornadofx - 如何在每个实例上将参数传递给 Fragment

Java Integer.MAX_VALUE 与 Kotlin Int.MAX_VALUE

在 Kotlin 函数上使用 Mokito anyObject() 时,指定为非 null 的参数为 null