我试图理解这里的泛型,但我很挣扎.我有一个简单的代码

interface A {
    
}

interface B {
    
}

class C : A, B {
    
}

fun <T: A> changeVal() : T {
    return C()
}

我得到以下错误Type mismatch: inferred type is C but T was expected.我做错了什么?

推荐答案

你写了一个函数,上面写着"给我命名一个A的子类.我将返回该子类的一个实例."这个签名是一个谎言,因为您总是返回C(),这是一个C实例,而不是A的所有T个子类的T.

仿制药建立了一种"面向所有人"的关系.调用方总是决定泛型实例化的对象,而不是被调用方.在你的情况下,你只需要返回A.

fun changeVal() : A

你要使用的功能叫做存在主义类型,这在Kotlin中是不可用的.在Haskell(带有适当的编译器扩展)中,签名可能看起来像

data AContainer where
  AVal :: forall a. a -> AContainer

changeVal :: AContainer
changeVal = ...

但Kotlin 没有这个功能.事实上,这正是OOP语言中的子类型所要做的:它说"我有一个具有这些特性的对象,但我不知道它的任何具体内容".所以你不需要泛型来表达这个模式.

Kotlin相关问答推荐

将基于注册的服务转换为流

何时使用figureEach

为什么";";.equals(1)在柯特林语中是有效的,但";";=1是无效的?

Groovy Gradle文件的Kotlin类似功能

kotlin - 挂起简单方法调用链时可能存在冗余分支

在 kotlin 原始字符串中转义三重引号

MyType.()在 Kotlin 中是什么意思?

Kotlin中用于调用常量名称的枚举类方法之间的区别

使用 StateFlow 时如何移除监听器?

Kotlin 函数有 2 个参数用于对 Map 或 List 进行排序

如何判断给定字符串是否多次包含另一个子字符串?

Kotlin:查找集合中最常见的元素

Kotlin:泛型、反射以及类型 T 和 T:Any 之间的区别

使用kotlinx协同程序测试中的类时出错

Kotlin 的类型具体化使哪些在 Java 或 Scala 中无法实现的成为可能?

如何捕获传递给模拟函数的参数并返回它?

Kotlin 的 Double.toInt() 中使用了哪种方法,舍入还是截断?

这是 Kotlin 中的错误还是我遗漏了什么?

如何限制kotlin协程的最大并发性

任务':app:kaptDebugKotlin'的Kotlin执行失败