仅将标记为具体化的类型传递给Kotlin泛型函数
假设我有以下代码:仅将标记为具体化的类型传递给Kotlin泛型函数,kotlin,kotlin-generics,kotlin-reified-type-parameters,Kotlin,Kotlin Generics,Kotlin Reified Type Parameters,假设我有以下代码: 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 {} 但我不想传递类对象,而是想将appleguice作为
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 {}
但我不想传递类对象,而是想将appleguice
作为类型传递:
val appleJuice : AppleJuice = makeJuice<AppleJuice>(Apple())
但现在我必须指定两种类型:
val appleJuice : AppleJuice = makeJuice<Apple, AppleJuice>(Apple())
val-appleguice:appleguice=makeJuice(Apple())
理论上,
Apple
type不应该是必需的,因为它已经从appleguice
type中知道了。有没有可能不传递不必要的类型,而只传递那些被具体化的类型?我看到您的解决方案的主要问题是,您在makeJuice
-方法上要求两个泛型类型。F
和J
都需要赋予该函数。虽然这对您(以及任何查看该方法的人)来说都是显而易见的,但我认为在运行时删除泛型类型时,这可能不是那么明显(但现在这主要是一个猜测)
如果您不介意您正在传递的水果与您期望的果汁的子类型不匹配,那么以下内容可能适合您:
inline fun <reified J : Juice<out Fruit>> makeJuice(fruit : Fruit) : J = TODO()
makeJuice
(/makeFrom
?)添加到Juice
类,例如
open class Juice<T : Fruit> {
fun makeFrom(fruit : T) { TODO() }
}
开放类果汁{
乐趣来自(水果:T){TODO()}
}
class JuiceMaker<F : Fruit>(val fruit : F) {
inline fun <reified J : Juice<F>> makeJuice() : J = TODO()
}
fun <F : Fruit> using(fruit : F) = JuiceMaker(fruit)
class果汁机(val水果:F){
inline fun makeJuice():J=TODO()
}
使用乐趣(水果:F)=果汁机(水果)
并称之为
using(Apple()).makeJuice<AppleJuice>()
使用(Apple()).makeJuice()
inline fun <reified J : Juice<out Apple>> Apple.makeJuice() : J = TODO()
inline fun Apple.makeJuice():J=TODO()
但您需要为所有类型指定它。不幸的是,以下措施行不通:
inline fun <F : Fruit, reified J : Juice<F>> F.makeJuice() : J = TODO()
inline fun F.makeJuice():J=TODO()
我们又遇到了同样的问题。。。并且需要指定
因此,如果您想用一个方法来处理所有问题,那么第三个变体可能是您的最佳选择(即使它使用了包装器)。在这种情况下,是否可以将
makeJuice
函数放在Juice
类中?如果您实际传入的水果不重要,然后您可以删除F
并使用Juice
和Fruit
参数来代替。@Mosius不,这是不可能的。它必须是静态方法扩展函数也是静态方法。。。扩展函数可以吗?;-)好。。。我不认为你可以有一个单一的静态函数和你想要的具体类型(也就是说,你实际上需要2个泛型类型)。我的答案中的变体3可能是您在不编写大量附加实现的情况下所能获得的最好版本。
using(Apple()).makeJuice<AppleJuice>()
inline fun <reified J : Juice<out Apple>> Apple.makeJuice() : J = TODO()
inline fun <F : Fruit, reified J : Juice<F>> F.makeJuice() : J = TODO()