使用泛型类型和直接将其上限类型用作函数中的参数类型之间的区别

时间:2019-02-14 12:57:27

标签: generics kotlin parameters

在Kotlin中,所有类型都被视为类。
假设有一个上限类定义:

open/abstract class UpperBound(...) { ... }

定义通用函数有什么区别

fun <T: UpperBound> function(param: T) { ... }

与直接使用上限定义函数相比

fun function(param: UpperBound) { ... }

由于在function内部,以param作为参数调用其他函数时,它将直接被视为UpperBound;并且在param上调用方法时,所有调用都将在对象的实际重写方法上执行吗?


更新:很抱歉,以下是该问题的错误示例。只是忽略它。

如果没有区别,以这种更复杂的方式定义诸如run之类的库函数的目的是什么

@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

代替

@kotlin.internal.InlineOnly
public inline fun <R> Any?.run(block: Any?.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

1 个答案:

答案 0 :(得分:4)

run的例子就是一个很好的例子。如果您将Any?定义为run及其参数block的接收者(我们称其为anyRun),您将收到一个{{1 }}内,您将只能在智能投射后调用Any?和类似方法:

toString

无论foo.anyRun { this?.toString() // only basic Any? methods visible here, since `this` is of type Any? this?.hashCode() } 是什么类型,这种情况都会发生。

另一方面,使用原始的通用实现,您将在lambda中返回具有原始类型的实例 ,例如:

foo