我有这种方法。
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
}
如何更改此方法以返回正确的类型?
答案 0 :(得分:6)
如果没有提供更多信息,很难给出一个明确的答案,但返回多种类型的最简单方法是让它们共享一个接口或超类:
interface Offer
class Addon : Offer
class Sale : Offer
class Plan : Offer
class CustomPlan : Offer
如果您的选项是静态的,您也可以使用sealed class
,这取决于您的使用案例。无论哪种方式,您都可以将函数返回类型设为Offer
有关详细信息,请参阅:
答案 1 :(得分:1)
以下是如何做到这一点:
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<T> {
companion object Types {
// "enum" values. Unfortunately Kotlin doesn't support
// type parameters for real enums
@JvmStatic
val ADDON = OfferType<Addon>()
@JvmStatic
val SALE = OfferType<Sale>()
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<String>) {
fun <T> getOffer(offers: OfferRepresentation, type: OfferType<T>): 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")
}
}
请注意UNCHECKED_CAST
函数中有getOffer
。您有责任确保使用正确的OfferType.ADDON
字段类型参数化OfferType.SALE
(OfferRepresentation
等)值,并且when
逻辑也正确,否则您将在运行时获取ClassCast
异常。
<强> UPD 即可。有一种替代实现使用了一些kotlin魔法,特别是reified types。使用此方法而不是使用单独的实体来定义要从getOffer
函数返回的字段,您只需指定显式类型参数。或者,您可以依赖隐式类型推断:
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 <reified T> 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<String>) {
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<OfferType.Addon>(offer)
println("$addon, $sale")
}
}
答案 2 :(得分:1)
您可以使用Any
作为返回类型的简单解决方案。 Any
与Java中的Object
不完全相同,但在这种情况下它足够接近https://kotlinlang.org/docs/reference/classes.html):
Kotlin中的所有课程都有一个共同的超类任何,这是默认的 对于没有声明超类型的类的超级:
class Example // Implicitly inherits from Any
因此,如果您的返回类型完全不相关,并且让它们共享一个公共接口没有意义,那么您可以使用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
}
答案 3 :(得分:-1)
您不能通过JVM从函数返回多于1个值。 你可以做的是返回一个Pair或Tuple或创建一个包含所有字段的Data类,然后将它们作为可选项
例如:
数据类Offer(val type1:String?= null,val type2:Integer?= 0)