在kotlin中使用lambda中的多个泛型类型

ant*_*009 7 generics lambda kotlin

Koltin 1.2.30
Run Code Online (Sandbox Code Playgroud)

我正在使用泛型和lambda函数.

以下工作没有泛型类型

fun onScanExt(): (Int, Int) -> Int = {
    num1, num2 -> num1 + num2

    num1 + num2
}
Run Code Online (Sandbox Code Playgroud)

但是,随着泛型:

fun <T, R> onScanExt(): (T, T) -> R = {
    num1, num2 -> num1 + num2

    num1 + num2
}
Run Code Online (Sandbox Code Playgroud)

我猜上面的内容不能正常工作,因为泛型类型可能不是Number类型,有人可以传入一个String,如果涉及计算,lambda将不知道如何处理String类型.

有关如何传递多个泛型并返回泛型类型的示例的任何建议?

提前谢谢了,

s1m*_*nw1 9

你是对的:使用它们时,泛型允许使用任何类型,甚至是那些不提供+操作符的类型.指定类型Number很容易.但是,它不会使函数编译:

fun <T : Number> onScanExt(): (T, T) -> T = { 
    num1, num2 -> num1 + num2
}
Run Code Online (Sandbox Code Playgroud)

(请注意,R在您的示例中不需要第二个类型参数.)

问题是,即使在合同Number中也不包括+运营商.这些是针对特定类型定义的Int,Double等等(参见来源).

诸如Kotlin之类的强类型语言将不允许这样的实现.


Ale*_*nov 6

用签名写任何东西都没有合理的方法

fun <T, R> onScanExt(): (T, T) -> R
Run Code Online (Sandbox Code Playgroud)

因为它说调用者可以选择任何TR,然后你需要R从两个Ts 获得; 但是T和之间没有关系R,所以你不能使用Ts.

你可以编译:例如,使用someExpression as R,或throw SomeException(),或无限循环.但这些都不是真的有用.

一般来说(C++是一个很大的例外;它的模板工作方式非常不同),泛型方法必须:

  1. 适用于所有类型(或者,在Java中,除了基元之外的所有类型).所以它只能使用所有类型的可用操作,而且这些操作很少.具有两个类型参数的示例将是

    fun <T1, T2> apply(f: T1 -> T2, x: T1) = f(x)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 处理满足某些约束的所有类型.不同的语言允许不同的约束; 例如,C#有一个非常大的集合,Scala有视图和上下文边界.据我所知,Kotlin只允许上界.特别是,没有约束表示"类型T有运算符+".所以你想要的功能无法写入.