标签: kotlin-generics

Kotlin Generics Java中的错误

鉴于以下三个kotlin类:

abstract class UseCase<T> {
    fun execute(action: Action<T>) {
    }
}

class ConcreteUseCase : UseCase<List<String>>()

class Action<T>
Run Code Online (Sandbox Code Playgroud)

我无法在java代码中编译以下行:

ConcreteUseCase s = new ConcreteUseCase();
s.execute(new Action<List<String>>());//<<<<<<< compilation error
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

错误说:

SomeClass的<java.util.List的<?扩展Type >> in Class不能应用于SomeClass <java.util.List <Type >>

我仍然是kotlin的新手,这可能是一个非常小的东西,但我似乎无法弄明白.我将不胜感激任何帮助.

java generics android kotlin kotlin-generics

10
推荐指数
1
解决办法
634
查看次数

Kotlin 用子类型覆盖 fun

我在继承包含基类型的方法/乐趣的接口时遇到问题,我想将其重写为实现它的类中的子类型。

到目前为止我已经有了界面

interface IModel {
    fun convert(dataModel: BaseDataModel)
}
Run Code Online (Sandbox Code Playgroud)

以及实现它的类:

class SettingsModel: IModel {
    override fun convert(dataModel: BaseDataModel) {
        // Conversion of models here

    }
}
Run Code Online (Sandbox Code Playgroud)

我还有 SettingsDataModel 它是:

class SettingsDataModel: BaseDataModel() {
}
Run Code Online (Sandbox Code Playgroud)

我想要实现的是对于每个实现 IModel 的类/模型,能够获取特定的 DataModel,例如:

class SettingsModel: IModel {
    override fun convert(dataModel: SettingsDataModel) {
        // Conversion of models here

    }
}
Run Code Online (Sandbox Code Playgroud)

无需投射它。我想我不能,因为它修改了乐趣的签名,使其不是真正的覆盖。我尝试使用泛型和泛型约束,但没有运气:

interface IModel {
    fun <T :BaseDataModel>convert(dataModel: T)
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用。有解决这个问题的方法吗?

generics inheritance kotlin kotlin-generics

5
推荐指数
1
解决办法
4204
查看次数

接口中的泛型函数以返回具体实现

我想向接口添加一个函数,该函数返回具体实现的对象。

因此,使用界面:

interface Content {
        fun <???> cloneMe(): ?
}
Run Code Online (Sandbox Code Playgroud)

和班级

class Music: Content
class Video: Content
Run Code Online (Sandbox Code Playgroud)

该功能cloneMe()的的Music类应该返回一个Music对象和函数cloneMe()中的Video类应返回一个Video对象。

我最接近的是:

interface Content {
    fun <T: Content> cloneMe(): T
}

class Music : Content {
    override fun <T : Content> cloneMe(): T {
        return Music() as T
    }
}
Run Code Online (Sandbox Code Playgroud)

那我就可以

val music: Music = Music().cloneMe<Music>()
Run Code Online (Sandbox Code Playgroud)

这里的问题是我必须进行未经检查的强制转换,“允许我”(即可以编译)执行

class Music : Content {
        override fun <T : Content> cloneMe(): T {
            return …
Run Code Online (Sandbox Code Playgroud)

generics kotlin kotlin-generics

5
推荐指数
1
解决办法
1174
查看次数

Kotlin"out"和"in"以及泛型 - 正确使用

我试图让一个普通的可怜人的数据持久化功能,将采取一个MutableSet数据类,并将其序列化到磁盘.我想要一些简单的原型设计,并且可以经常在集合上调用"save()",这样如果我的进程被杀死,我可以稍后使用已保存条目的"load()"恢复.

但即使重读了Generics页面,我也没有完全区分'*','in','out'和'Nothing'之间的区别.这个SEEMS可以在不抛出错误的情况下工作,但我不明白为什么他们都"出局",我认为一个人必须"进入"...或者更可能我理解Kotlin Generics完全错误.这样做有正确的方法吗?

/** Save/load any MutableSet<Serializable> */
fun MutableSet<out Serializable>.save(fileName:String="persist_${javaClass.simpleName}.ser") {
    val tmpFile = File.createTempFile(fileName, ".tmp")
    ObjectOutputStream(GZIPOutputStream(FileOutputStream(tmpFile))).use {
        println("Persisting collection with ${this.size} entries.")
        it.writeObject(this)
    }
    Files.move(Paths.get(tmpFile), Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING)
}

fun MutableSet<out Serializable>.load(fileName:String="persist_${javaClass.simpleName}.ser") {
    if (File(fileName).canRead()) {
        ObjectInputStream(GZIPInputStream(FileInputStream(fileName))).use {
            val loaded = it.readObject() as Collection<Nothing>
            println("Loading collection with ${loaded.size} entries.")
            this.addAll(loaded)
        }
    }
} 

data class MyWhatever(val sourceFile: String, val frame: Int) : Serializable
Run Code Online (Sandbox Code Playgroud)

然后能够启动任何应用程序

val mySet = mutableSetOf<MyWhatever>()
mySet.load()
Run Code Online (Sandbox Code Playgroud)

generics kotlin kotlin-generics

3
推荐指数
1
解决办法
628
查看次数

仅将标记为已归类的类型传递给Kotlin泛型函数

假设我有以下代码:

open class Fruit
class Apple : Fruit()
open class Juice<T : Fruit>
class AppleJuice : Juice<Apple>()

fun <F : Fruit, J : Juice<F>> makeJuice(juiceClass : Class<J>, fruit : F) : J {}
Run Code Online (Sandbox Code Playgroud)

我这样调用该函数:

val appleJuice : AppleJuice = makeJuice(AppleJuice::class.java, Apple())
Run Code Online (Sandbox Code Playgroud)

但是,我不想传递类对象,而是希望将其AppleJuice作为类型传递:

val appleJuice : AppleJuice = makeJuice<AppleJuice>(Apple())
Run Code Online (Sandbox Code Playgroud)

我重构了我的功能以内联reified

inline fun <F : Fruit, reified J : Juice<F>> makeJuice(fruit : F) : J {}
Run Code Online (Sandbox Code Playgroud)

但是现在我必须指定两种类型:

val appleJuice : AppleJuice = makeJuice<Apple, AppleJuice>(Apple())
Run Code Online (Sandbox Code Playgroud)

从理论上讲,Apple不需要类型,因为它已经从AppleJuice …

kotlin kotlin-generics kotlin-reified-type-parameters

3
推荐指数
1
解决办法
319
查看次数

为什么Kotlin不能在接口和从它派生的泛型类型之间进行智能转换?

我有以下课程:

abstract class PresenterActivity<S : ViewState, I : ViewIntent> : AppCompatActivity() { 
    open fun initViewIntent(): I {
        return object : ViewIntent{} // type mismatch on this line
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到一个预编译错误,说明:

Type mismatch
Required: I
Found: <S, I>
Run Code Online (Sandbox Code Playgroud)

为了解决这个预编译错误,我将ViewIntent对象转换为I:

abstract class PresenterActivity<S : ViewState, I : ViewIntent> : AppCompatActivity() { 
    open fun initViewIntent(): I {
        @Suppress("UNCHECKED_CAST")
        return object : ViewIntent{} as I
    }
}
Run Code Online (Sandbox Code Playgroud)

但为什么Kotlin不能检测到I必须从中衍生出来ViewIntent并且聪明地施展它?

kotlin kotlin-generics

2
推荐指数
2
解决办法
206
查看次数

(kotlin)editText.toString().toInt()在anroid工作室中不起作用

val editText1 = findViewById<EditText>(R.id.editText1);

if(comNum != editText1.toString().toInt() ){

 View4.text = "??"
            } else View4.text = "??"
Run Code Online (Sandbox Code Playgroud)

安装 apk无法正常工作.我认为edittext.toString.toInt是错的.

android apk kotlin kotlin-generics

1
推荐指数
1
解决办法
246
查看次数