Kotlin – 我如何从我的方法返回不同的types?

我有这个方法。

private fun getOffer(offers: OfferRepresentation, type: OfferType): ???? { return when (type) { OfferType.ADDON -> offers.addon OfferType.SALE -> offers.sale OfferType.PLAN -> offers.plan OfferType.CUSTOMPLAN -> offers.customPlan } 

我怎样才能改变这种方法来返回正确的types?

如果不提供更多信息,很难给出一个二元的答案,但返回多种types的最简单的方法是让它们共享一个接口或超类:

 interface Offer class Addon : Offer class Sale : Offer class Plan : Offer class CustomPlan : Offer 

如果您的选项是静态的,您也可以使用sealed class ,这取决于您的使用情况。 无论哪种方式,您可以只有函数返回types是Offer

有关更多信息,请参阅

  • 接口
  • 密封类

以下是你如何做到这一点:

 object Main { // concrete class for all "enum" values (such as OfferType.ADDON or OfferType.SALE) // that get passed to `getOffer` as second param class OfferType { companion object Types { // "enum" values. Unfortunately Kotlin doesn't support // type parameters for real enums @JvmStatic val ADDON = OfferType() @JvmStatic val SALE = OfferType() data class Addon(val name: String) data class Sale(val name: String) } } data class OfferRepresentation( val addon: OfferType.Types.Addon, val sale: OfferType.Types.Sale ) @JvmStatic fun main(args: Array) { fun  getOffer(offers: OfferRepresentation, type: OfferType): T { @Suppress("UNCHECKED_CAST") return when (type) { OfferType.ADDON -> offers.addon as T OfferType.SALE -> offers.sale as T else -> throw IllegalArgumentException("Unsupported type $type") } } val offer = OfferRepresentation( OfferType.Types.Addon("addon"), OfferType.Types.Sale("sale") ) // types are specified explicitly for the sake of demonstration val addon: OfferType.Types.Addon = getOffer(offer, OfferType.ADDON) val sale: OfferType.Types.Sale = getOffer(offer, OfferType.SALE) println("$addon, $sale") } } 

请注意, getOffer函数中有一个UNCHECKED_CAST 。 您有责任确保OfferType.ADDONOfferType.SALE等)值使用正确的OfferRepresentation的字段types进行参数化,并且逻辑也是正确的,否则将在运行时得到ClassCastexception。


UPD 。 有一个替代的实现,使用了一点kotlin魔术,具体来说, 物化types 。 通过这种方法,您可以不使用单独的实体来定义要从getOffer函数返回的字段,而只需指定显式types参数。 另外,你可以依靠隐式types推断:

 object Main2 { object OfferType { data class Addon(val name: String) data class Sale(val name: String) } data class OfferRepresentation( val addon: OfferType.Addon, val sale: OfferType.Sale ) //reified type parameters require function to be inline inline fun  getOffer(offers: OfferRepresentation): T { @Suppress("UNCHECKED_CAST") return when (T::class) { OfferType.Addon::class -> offers.addon as T OfferType.Sale::class -> offers.sale as T else -> throw IllegalArgumentException("Unsupported type ${T::class}") } } @JvmStatic fun main(args: Array) { val offer = OfferRepresentation( OfferType.Addon("addon"), OfferType.Sale("sale") ) // types needed to be specified explicitly here val addon: OfferType.Addon = getOffer(offer) val sale: OfferType.Sale = getOffer(offer) // alternatively `getOffer` should be invoked like this: getOffer(offer) println("$addon, $sale") } } 

你有使用Any作为你的返回types的微不足道的解决方案。 Any都不完全像Java中的Object ,但在这种情况下足够接近( https://kotlinlang.org/docs/reference/classes.html ):

Kotlin中的所有类都有一个公共的超类Any ,这是一个没有声明超类的类的默认超类:

 class Example // Implicitly inherits from Any 

所以如果你的返回types是完全不相关的,并且让你共享一个通用接口是没有意义的,那么你可以使用Any:

 private fun getOffer(offers: OfferRepresentation, type: OfferType): Any { return when (type) { OfferType.ADDON -> offers.addon OfferType.SALE -> offers.sale OfferType.PLAN -> offers.plan OfferType.CUSTOMPLAN -> offers.customPlan } 

您不能从JVM的函数返回多个值。 你可以做的是返回一个Pair或Tuple或创建一个Data类的所有领域,然后把它们作为可选项

例如:

数据类提供(val type1:String?= null,val type2:Integer?= 0)