泛型<T>类实例列表 – 调用接受T的函数

huangapple go评论57阅读模式
英文:

List of generic<T> class instances - call function that takes T

问题

val t = list[0].get()
t.foo = bar
(list[0] as MyClass<BaseClass>).process(t)
英文:

I have a class that looks like this:

class MyClass&lt;T : BaseClass&gt; {
    fun get(): T
    fun process(thing: T)
}

If I had a single instance of this class of type X, for example, I could do:

val instance: MyClass&lt;X&gt; = getInstance()
val t = instance.get()
t.foo = bar
instance.process(t)

However, instead of having just one, I have a list of them, each having a different type as T:

val list: List&lt;MyClass&lt;*&gt;&gt; = getInstances()
val t = list[0].get()
t.foo = bar
// Error here: type mismatch - BaseClass cannot be converted to Nothing
list[0].process(t)

That is because MyClass&lt;*&gt;.get() returns BaseClass and, in contrast, MyClass&lt;*&gt;.process() takes Nothing as its argument, so it cannot be called.

How can I call process() on one of the list members, with the result of get()?

So far, my solution is:

val t = list[0].get()
t.foo = bar
@Suppress(&quot;UNCHECKED_CAST&quot;)
(list[0] as MyClass&lt;BaseClass&gt;).process(t)

Is there a better way?

答案1

得分: 4

You can simply extract the piece of code where you need the T into a generic function (which kinda captures the actual generic type of MyClass for the body of your function):

fun <T> MyClass<T>.getAndProcess(foo: Foo) {
    val t = get()
    t.foo = foo
    process(t)
}

This way of extracting into a generic function basically allows you, like in math, to declare "let T be the T of that MyClass instance".

Then you can call getAndProcess() on a MyClass<*> like this:

val list: List<MyClass<*>> = getInstances()
list[0].getAndProcess(foo = bar)
英文:

You can simply extract the piece of code where you need the T into a generic function (which kinda captures the actual generic type of MyClass for the body of your function):

fun &lt;T&gt; MyClass&lt;T&gt;.getAndProcess(foo: Foo) {
    val t = get()
    t.foo = foo
    process(t)
}

This way of extracting into a generic function basically allows you, like in math, to declare "let T be the T of that MyClass instance".

Then you can call getAndProcess() on a MyClass&lt;*&gt; like this:

val list: List&lt;MyClass&lt;*&gt;&gt; = getInstances()
list[0].getAndProcess(foo = bar)

huangapple
  • 本文由 发表于 2023年5月6日 20:49:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76188984.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定