kotlin - Any? 之间的联合类型和单位

标签 kotlin

我正在尝试编写一个允许我执行此操作的高阶函数:

blah1 { em ->
    // do some stuff here
}

还有这个:

blah2 { em ->
    // do some stuff here
    listOf("1","2","3")
}

在第一个示例中,我没有返回任何内容,而在第二个示例中,我返回了一个字符串列表。

这适用于第一个:

inline fun blah1(f: (em: EM) -> Unit): Result {
    f(em)
    return Result()
}

对于第二个,我需要一个不同的返回类型:

inline fun blah2(f: (em: EM) -> Any?): Result {
    val res = f(em)
    when (res) {
        is List<*> -> res.forEach { item ->
            // do something with item
        }
    }
    return Result()
}

是否可以将 blah1blah2 结合起来,这样如果我这样做:

blah { em ->

}

val res = f(em) res 将是 Unit 类型,当我这样做时:

blah { em ->
   listOf("1","2","3")
}

val res = f(em) res 将是 List 类型?

我试过这样做:

inline fun blah(
    noinline f1: (em: EM) -> Unit = f1fun,
    noinline f2: (em: EM) -> Any? = f2fun
): Result {
    f1(em)
    f2(em)?.let { res ->
        when (res) {
            is List<*> -> res.forEach { item ->
                // do something with item
            }
        }
    }
    return Result()
}

val f1fun: (em: EntityManager) -> Unit = { Unit }
val f2fun: (em: EntityManager) -> Any? = { null }

...但现在我是否这样做

blah { em ->
    // code here    
}

blah { em ->
    // code here
    listOf("1", "2")
}

f2 的 lambda 总是被执行。

有没有一种方法可以让 blah { with or without statement } 允许您将该值收集为 Any? 如果语句确实在lambda,当没有语句存在时,将其视为 Unit lambda?

这个: inline fun blah2(f: (em: EM) -> Any?): 结果 {

在某些情况下无法编译:

blah2 {
   k = k + 1
}

即使这工作正常:

blah2 {

}

这很好用:

blah2 {
  k++
}

更新:同时记录了一个错误:https://youtrack.jetbrains.com/issue/KT-20215

最佳答案

k = k + 1 是一个赋值语句,它不是 Kotlin 中的表达式,因此它不会计算为 Unit 或任何其他类型。


Why are assignments with no type at all taken into account when the compiler is looking for expressions?

考虑以下短程序:

fun main(args: Array<String>) {
    val result = num { a ->
        var b = a * 5
        // ...put whatever code you want here
        // ...and here
        b++ // <- the last line matters
    }
}

fun num(f: (i: Int) -> Int): Int {
    return f(5)
}

lambda 主体内的最后一行,这是重要的行,它必须是一个表达式(在本例中为 Int),因为它是此 lambda 返回的内容。

那么,最后一行可以是b = b + 1吗?不,因为它不是表达式,因此不能原样返回。

即使您使用 AnyUnit 作为返回类型也不会改变 b = b + 1 两者都不是的事实那些。

What I had to do to get around this was do this: blah2 { k = k + 1; Unit }, otherwise my lambda didn't work

是的,因为 Unit 是一个有效的表达式并且 blah2 { k = k + 1;单位

相同
blah2 { 
   k = k + 1 
   Unit // again, last line matters
}

关于kotlin - Any? 之间的联合类型和单位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46160539/

相关文章:

kotlin - 如何使用 BouncyCaSTLe 从 java/kotlin 中的文件/字符串中读取 RSA 公钥

maven - 如何将Maven插件转换为Gradle插件(maven-surefire-puglin)?

java - Kotlin 反射与 Java 的互操作性

android - Kotlin - MainActivity 扩展了 AppCompatActivity,找不到 onRequestPermissionsResult 函数且无法覆盖

intellij-idea - Kotlin - DSL 颜色样式

android - 我的anko-sqlite数据库对象无法调用

android - TextInputEditText调整文本大小

android - 对一组闪烁的可组合项进行动画处理,控制同步/计时

gradle - 运行时出现 NoClassDefFoundError

Kotlin:如果 E 是实现接口(interface) I 的枚举类,则从返回类型为 Array<I> 的函数返回 Array<E>