Kotlin 中 lambda 函数参数的默认值

Nev*_*eps 5 lambda kotlin

我在构造函数中有这样的带有 lambda 的枚举

enum class EventType(
    val getInfoBlocks: (Book, AuditEntity?) -> List<InfoBlock>? = { _, _ -> emptyList() }
) {...}
Run Code Online (Sandbox Code Playgroud)

现在我像这样使用这个 lambda 函数:

data = it.getInfoBlocks.invoke(deal, null)
Run Code Online (Sandbox Code Playgroud)

我可以不用 null 吗?有没有办法为 null lambda 函数参数设置默认值?

Moi*_*ira 5

TL;DR:函数类型不能有与其关联的默认参数值。
这是只有命名(非匿名)函数才能做到的事情。

但是,可能有更好的解决方案来解决您的问题。


不可以,匿名函数(即 lambda 表达式和fun块)不允许为其参数指定默认值。

然而,您的建议比这更复杂:您似乎希望默认值与函数的type相关联,因此无论哪个函数分配给此属性,它都会保持不变。

因为这个默认值取决于函数分配给的变量的类型,为了实现这一点,类型系统需要一种方法来将默认参数值存储在函数的类型信息中(即类似于(Book, AuditEntity? = null) -> List<InfoBlock>?),并且没有办法做到这一点。


但是,由于这是一个枚举,因此无需将匿名函数存储为属性;只需声明一个虚函数并根据需要重写它:

enum class EventType {

    // Type1 has the default implementation
    Type1,
    
    // Type2 has its own implementation
    Type2 {
        override fun getInfoBlocks(book: Book, entity: AuditEntity?): List<InfoBlock>? {
            // Do something else
            return foo()
        }
    };
    
    // Default implementation
    open fun getInfoBlocks(book: Book, entity: AuditEntity? = null): List<InfoBlock>? {
        return emptyList()
    }

}
Run Code Online (Sandbox Code Playgroud)

(请注意,需要分号来终止常量列表。)


类似于(但不相同)为什么不可能在匿名函数本身中指定默认参数(另请参见这个问题),即:

{ a: Any, b: Any? = null -> foo() }
Run Code Online (Sandbox Code Playgroud)

由于这甚至是不可能的,因此没有办法为整个函数系列指定默认参数是有道理的。