2017-11-22 6 views
2

私はこの方法を持っています。Kotlin - どのように私のメソッドから別の型を返すことができますか?

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 
    } 

どのようにこのメソッドを変更して正しいタイプを返すことができますか?

+1

OfferRepresentationクラスの外観はどうなっていますか? – fejd

+0

@fejd OfferRepresentationには、addon、sale、planまたはcustomPlanの4つの属性(offerTypes)があります。 OfferRepresentationに計画(または他のもの)がある場合、他の属性は必ずnullです。 –

答えて

-1

JVMによって関数から2つ以上の値を返すことはできません。

データクラスオファー(ヴァル・TYPE1::文字列= nullで、valのTYPE2?あなたは何ができるか は、ペアまたはタプルを返すか、すべてのフィールドとデータクラスを作成し、オプションの

例:としてそれらを持っています:?ここでは= 0)

0

整数は、あなたがそれを行うことができる方法である。

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_CASTgetOffer内の関数があること。 OfferType.ADDONOfferType.SALEなど)の値が正しいOfferRepresentationのフィールドタイプでパラメータ化され、whenロジックも正しく設定されていることを確認することは、あなたの責任です。そうでなければ、実行時にClassCast例外が発生します。


UPD。コットリンの魔法を少し使った別の実装、具体的には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") 
    } 
} 
4

それはあなたがより多くの情報を与えることなく、あなたにdifinitive答えを与えるのは難しいですが、複数のタイプを返すための最も簡単な方法は、それらすべてのインタフェースまたはスーパークラスを共有することです。

interface Offer 

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

オプションが静的な場合は、sealed classを使用することもできます。使用するケースによって異なります。いずれにせよ、あなたは、単に関数の戻り値の型が詳細についてはOffer

もしていることができます参照してください。

0

をあなたのようAnyを使用しての些細なソリューションを持っています戻り値の型。Anyは正確にJavaでObjectのようではありませんが、それはこの場合(https://kotlinlang.org/docs/reference/classes.html)で十分に近いです:

Kotlinのすべてのクラスが共通のスーパーどれを持って、それが宣言されていないスーパータイプとクラスのデフォルト スーパーです:

class Example // Implicitly inherits from 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 
    } 
関連する問題