Kotlin - 类型与泛型 return 类型和子类不匹配
Kotlin - type mismatch with generic return type and subclass
希望大家在疫情中保持健康:)
我需要一些帮助来弄清楚我在这里做错了什么,TIA!另外,我对 Kotlin 有点陌生,如果这是一个愚蠢的问题,我很抱歉。
我正在尝试扩展 class 并实现在 java 库 (AndroidX) 中定义的接口。但是,当我尝试实现接口函数时,我的 return 值出现类型不匹配错误。由于我使用的是 AndroidX 库中定义的接口,因此无法简单地更改接口函数签名来构建它。
我基本上是将这个其他 SO 答案转换为 Kotlin:
开发 machine/IDE 信息:
Android Studio 3.6.1
构建 #AI-192.7142.36.36.6241897,构建于 2020 年 2 月 26 日
运行时版本:1.8.0_212-release-1586-b04 amd64
VM:JetBrains 的 OpenJDK 64 位服务器 VM s.r.o
Windows 8.1 6.3
GC:ParNew,ConcurrentMarkSweep
内存:1237M
核心数:8
注册表:ide.new.welcome.screen.force=true
非捆绑插件:org.jetbrains.kotlin、com.google.services.firebase
我试图用下面的代码概括这个错误,希望能为你解决其他 SO 问题节省一些精力,而我在这个概括的代码中遇到了同样的编译器错误。
open class LibraryClassA {
}
open class LibraryClassB {
val retval = LibraryClassA()
// this kotlin signature seems to be inferred/transcribed from java by the IDE/compiler
open fun <T : LibraryClassA?> foobar(): T? {
return null
}
}
class MyClass : LibraryClassB() {
override fun <T : LibraryClassA?> foobar(): T? {
return retval // compiler error on this line - type mismatch, Required T?, Found LibraryClassA
}
}
这是根本问题。
当你写
fun <T : LibraryClassA?> foobar(): T? { ... }
你声明 foobar
的调用者 可以指定他们想要的 LibraryClassA
的任何子类,并获得 [=32= 的实例]那个。例如,如果有
class FooClass : LibraryClassA() { ... }
有人可以打电话
val myFooClass: FooClass = myLibraryClassB.foobar<FooClass>()
并希望它能起作用。你所拥有的将 not 为此工作,因为你将拥有的将是一个 LibraryClassA
实例,not a FooClass
实例。
如果您打算返回 LibraryClassA?
的 一些 子类,但是 LibraryClassB
的实现控制他们得到什么,而不是调用者,那么该函数的正确类型是
fun foobar(): LibraryClassA? { ... }
另一个答案解释了编译器错误背后的原因,但由于我无法轻松修改我正在使用的库,因此解决我的问题的方法是进行转换并取消警告。
我的最终代码如下所示:
override fun <T : Preference?> findPreference(key: CharSequence): T? {
// unchecked cast needed since we can't modify the library code to call this with the
// correct type parameter, and we can't modify the function signature
@Suppress("UNCHECKED_CAST")
return this.preference as T
}
希望大家在疫情中保持健康:)
我需要一些帮助来弄清楚我在这里做错了什么,TIA!另外,我对 Kotlin 有点陌生,如果这是一个愚蠢的问题,我很抱歉。
我正在尝试扩展 class 并实现在 java 库 (AndroidX) 中定义的接口。但是,当我尝试实现接口函数时,我的 return 值出现类型不匹配错误。由于我使用的是 AndroidX 库中定义的接口,因此无法简单地更改接口函数签名来构建它。
我基本上是将这个其他 SO 答案转换为 Kotlin:
开发 machine/IDE 信息: Android Studio 3.6.1 构建 #AI-192.7142.36.36.6241897,构建于 2020 年 2 月 26 日 运行时版本:1.8.0_212-release-1586-b04 amd64 VM:JetBrains 的 OpenJDK 64 位服务器 VM s.r.o Windows 8.1 6.3 GC:ParNew,ConcurrentMarkSweep 内存:1237M 核心数:8 注册表:ide.new.welcome.screen.force=true 非捆绑插件:org.jetbrains.kotlin、com.google.services.firebase
我试图用下面的代码概括这个错误,希望能为你解决其他 SO 问题节省一些精力,而我在这个概括的代码中遇到了同样的编译器错误。
open class LibraryClassA {
}
open class LibraryClassB {
val retval = LibraryClassA()
// this kotlin signature seems to be inferred/transcribed from java by the IDE/compiler
open fun <T : LibraryClassA?> foobar(): T? {
return null
}
}
class MyClass : LibraryClassB() {
override fun <T : LibraryClassA?> foobar(): T? {
return retval // compiler error on this line - type mismatch, Required T?, Found LibraryClassA
}
}
这是根本问题。
当你写
fun <T : LibraryClassA?> foobar(): T? { ... }
你声明 foobar
的调用者 可以指定他们想要的 LibraryClassA
的任何子类,并获得 [=32= 的实例]那个。例如,如果有
class FooClass : LibraryClassA() { ... }
有人可以打电话
val myFooClass: FooClass = myLibraryClassB.foobar<FooClass>()
并希望它能起作用。你所拥有的将 not 为此工作,因为你将拥有的将是一个 LibraryClassA
实例,not a FooClass
实例。
如果您打算返回 LibraryClassA?
的 一些 子类,但是 LibraryClassB
的实现控制他们得到什么,而不是调用者,那么该函数的正确类型是
fun foobar(): LibraryClassA? { ... }
另一个答案解释了编译器错误背后的原因,但由于我无法轻松修改我正在使用的库,因此解决我的问题的方法是进行转换并取消警告。
我的最终代码如下所示:
override fun <T : Preference?> findPreference(key: CharSequence): T? {
// unchecked cast needed since we can't modify the library code to call this with the
// correct type parameter, and we can't modify the function signature
@Suppress("UNCHECKED_CAST")
return this.preference as T
}