gpt4 book ai didi

generics - 如何在 Kotlin 中编写强类型泛型扩展函数?

转载 作者:行者123 更新时间:2023-12-04 19:25:58 26 4
gpt4 key购买 nike

关注通用 部分。

假设我有这个扩展功能:

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")
}
}
}

最佳答案

这似乎是由于 Collection 上的差异造成的。接口(interface)的参数,定义为Collection<out E> .

这意味着 Collection<Any>Collection<E> 的父类(super class)型,所以(显然)Collection<Any>.myContains()可以在 Collection<Int> 上调用扩展程序.

您可以通过将其替换为不变量 MutableCollection 来确认这一点。 (还有 listOf()mutableListOf() );然后你会得到预期的编译时“类型不匹配”错误。

不过,这让我很惊讶。我猜编译器必须推断出 E同时使用接收器类型和参数类型。 (任何人都可以证实这一点吗?)而且,正如您所指出的,它具有阻止更严格的类型安全性的烦人效果。

关于generics - 如何在 Kotlin 中编写强类型泛型扩展函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57224118/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com