Kotlin 中参数数量可变的 Lambda 类型?
Lambda type with variable number of args in Kotlin?
是否可以接收作为内联 lambda 参数的函数类型,该函数类型具有 保证 return 类型 R
但参数数量可变 ?为简单起见,请考虑以下内容:
inline fun <R> Boolean?.tfn(tru:()->R, fls:()->R, nul:()->R) =
if (this == null) nul() else if (this) tru() else fls()
假设我有 其他内联函数也采用 lambda 参数,其类型可能是 (A)->R
或 (A,B)->R
或 (A,B,C)->R
,我想将其参数传递给此函数。它们都将提供一个 R
,但必须调用它们才能获得 R
,而不知道此函数中参数的 number/type/values。有没有办法将上面的函数一般修改为:
- 捕获任何 lambda 参数的一般情况 returning
R
作为其输入
- 避免对将调用此函数的其他内联函数进行任何更改
- 保持在线效率
这是不可能的
Kotlin 使用静态、强类型,编译器需要在编译时知道 lambda 参数的确切类型。
内部 lambdas 实际上是 kotlin.jvm.functions
接口之一的实现(对于 JVM 或 Android),就像这个:
/* A function that takes 1 argument. */
public interface Function1<in P1, out R>
这些接口定义了参数的确切数量及其类型。因此,无法在 Kotlin 中创建 vararg
lambda。
这当然与JVM中的vararg
只是一个内部使用普通数组的语法糖有关,本身并不是一个类型系统构造,所以你不能把vararg
当作像类型。
依赖类型
解决你的问题的一个建议是使用Array
或Collection
作为函数参数,或者传入任意Function<R>
,但这种解决方案的方式有限没有办法静态地强制每个传递函数的相同数量的参数,因为类型系统本身不知道 collection/array 的大小或 Function<R>
.[=20 的参数计数=]
要完全解决您的问题,您需要一种具有 dependent type 的语言
系统.
是否可以接收作为内联 lambda 参数的函数类型,该函数类型具有 保证 return 类型 R
但参数数量可变 ?为简单起见,请考虑以下内容:
inline fun <R> Boolean?.tfn(tru:()->R, fls:()->R, nul:()->R) =
if (this == null) nul() else if (this) tru() else fls()
假设我有 其他内联函数也采用 lambda 参数,其类型可能是 (A)->R
或 (A,B)->R
或 (A,B,C)->R
,我想将其参数传递给此函数。它们都将提供一个 R
,但必须调用它们才能获得 R
,而不知道此函数中参数的 number/type/values。有没有办法将上面的函数一般修改为:
- 捕获任何 lambda 参数的一般情况 returning
R
作为其输入 - 避免对将调用此函数的其他内联函数进行任何更改
- 保持在线效率
这是不可能的
Kotlin 使用静态、强类型,编译器需要在编译时知道 lambda 参数的确切类型。
内部 lambdas 实际上是 kotlin.jvm.functions
接口之一的实现(对于 JVM 或 Android),就像这个:
/* A function that takes 1 argument. */
public interface Function1<in P1, out R>
这些接口定义了参数的确切数量及其类型。因此,无法在 Kotlin 中创建 vararg
lambda。
这当然与JVM中的vararg
只是一个内部使用普通数组的语法糖有关,本身并不是一个类型系统构造,所以你不能把vararg
当作像类型。
依赖类型
解决你的问题的一个建议是使用Array
或Collection
作为函数参数,或者传入任意Function<R>
,但这种解决方案的方式有限没有办法静态地强制每个传递函数的相同数量的参数,因为类型系统本身不知道 collection/array 的大小或 Function<R>
.[=20 的参数计数=]
要完全解决您的问题,您需要一种具有 dependent type 的语言 系统.