【发布时间】:2019-12-05 00:56:50
【问题描述】:
关注strong和通用部分。
假设我有这个扩展功能:
fun <E> Collection<E>.myContains(item: E) : Boolean {
// quite pointless, I know, but a simple example
return item in this
}
目的是编写一个只接受集合元素类型的函数(E),但这没有经过编译器验证?!
val isItInside: Boolean = listOf(1, 2).myContains("1")
愉快地编译。我的猜测是E 被推断为Any。
如何在 Kotlin 类型系统/泛型中强制执行此限制?
(Kotlin 版本 1.3.41)
原始上下文
尝试编写一个小型断言框架的练习。稍微复杂一点,但试图得到上面最简单的复制。
class Asserter<T>(val value: T)
infix fun <T> T.should(block: Asserter<T>.() -> Unit) =
Asserter(this).block()
fun <T : Collection<*>> Asserter<T>.haveSize(size: Int) {
check(this.value.size == size) {
"expecting ${this.value} to be of size $size"
}
}
fun <E, T : Collection<E>> Asserter<T>.contain(item: E) {
check(item in this.value) {
"$item does not exist in $item"
}
}
class ShouldTest {
@Test fun intList() {
listOf(1, 2) should {
haveSize(2)
contain(1)
contain("2") // this shouldn't compile
}
}
@Test fun stringList() {
listOf("1", "2") should {
haveSize(2)
contain(1) // this shouldn't compile
contain("2")
}
}
}
【问题讨论】:
-
(问题从一开始就很清楚;我认为原始上下文除了大容量之外并没有增加太多。在链接中会更好,还是省略?)
标签: generics kotlin extension-methods type-inference