2015-06-14 15 views
34

कोटलिन में पैटर्न मिलान अच्छा है और तथ्य यह है कि यह अगले पैटर्न मैच को निष्पादित नहीं करता है 90% उपयोग मामलों में अच्छा है।"कब" कथन बनाम जावा "स्विच" कथन

एंड्रॉयड में, जब डेटाबेस अद्यतन किया जाता है, हम जावा प्रॉपर्टी को बदलना कोड कि तरह लग रही है करने के लिए अगले मामले पर जाने के लिए अगर हम एक ब्रेक डाल नहीं का उपयोग करें:

switch (oldVersion) { 
    case 1: upgradeFromV1(); 
    case 2: upgradeFromV2(); 
    case 3: upgradeFromV3(); 
} 

किसी के साथ किसी ऐप है तो अगर डीबी के संस्करण 1 और डीबी v2 के साथ ऐप संस्करण को याद किया, उसे निष्पादित सभी आवश्यक अपग्रेड कोड मिलेगा।

when (oldVersion) { 
    1 -> { 
     upgradeFromV1() 
     upgradeFromV2() 
     upgradeFromV3() 
    } 
    2 -> { 
     upgradeFromV2() 
     upgradeFromV3() 
    } 
    3 -> { 
     upgradeFromV3() 
    } 
} 

यहाँ हम केवल 3 संस्करण है, कल्पना जब डीबी संस्करण 19 तक पहुँच जाता है: जब से एक ही तरह से काम कर रहा बनाता करने के लिए वैसे भी/

Kotlin में बदल दिया है, हम एक गड़बड़ की तरह मिलता है स्विच? मैंने भाग्य के बिना जारी रखने की कोशिश की।

+0

बस https://youtrack.jetbrains.com/issue/KT-771 पर तो किसी भी तरीके को ठोकर खाई? –

+1

मुझे सांख्यिकीय रूप से लगता है (कोई सबूत नहीं, लेकिन मुझे यकीन है कि कोटलिन टीम ने आंकड़ों का फैसला करने के लिए आंकड़े इस्तेमाल किए हैं) कि जावा में 'स्विच' लगभग हर मामले में लगभग 'ब्रेक' होता है, इसलिए यह सामान्य मामले के लिए असुविधाजनक है। –

उत्तर

50

सरल लेकिन अधिक शब्दों वाले समाधान है:

if (oldVersion <= 1) upgradeFromV1() 
if (oldVersion <= 2) upgradeFromV2() 
if (oldVersion <= 3) upgradeFromV3() 

एक अन्य संभावित समाधान function references साथ:

fun upgradeFromV0() {} 
fun upgradeFromV1() {} 
fun upgradeFromV2() {} 
fun upgradeFromV3() {} 

val upgrades = arrayOf(::upgradeFromV0, ::upgradeFromV1, ::upgradeFromV2, ::upgradeFromV3) 

fun upgradeFrom(oldVersion: Int) { 
    for (i in oldVersion..upgrades.lastIndex) { 
     upgrades[i]() 
    } 
} 
+0

ग्रेट उत्तर, लेकिन आप लूप –

10

कैसे इस बारे में:

fun upgradeFromV3() {/* some code */} 
fun upgradeFromV2() {/* some code */ upgradeFromV3()} 
fun upgradeFromV1() {/* some code */ upgradeFromV2()} 
fun upgradeFromV0() {/* some code */ upgradeFromV1()} 

fun upgrade(oldVersion: Int) { 
    when (oldVersion) { 
     1 -> upgradeFromV1() 
     2 -> upgradeFromV2() 
     3 -> upgradeFromV3() 
    } 
} 
13

संपादित करें: नीचे मूल प्रतिक्रिया। यहाँ मैं वर्तमान में क्या कर रहा है:

fun upgrade() { 
    fun upgradeFromV1() { /* Do stuff */ } 
    fun upgradeFromV3() { /* Do stuff */ } 

    tailrec fun upgradeFrom(version: Int): Unit = when (version) { 
     LATEST_VERSION -> { 
      Config.version = version 
     } 1 -> { 
      upgradeFromV1() 
      upgradeFrom(2) 
     } in 2..3 -> { 
      upgradeFromV3() 
      upgradeFrom(4) 
     } else -> { 
      Log("Uncaught upgrade from $version") 
      upgradeFrom(version+1) 
    } 

    upgradeFrom(Config.version) 
} 

यहाँ जवाब @ C.A.B पर एक परिवर्तन हो। दिया:

fun upgrade(oldVersion: Int) { 
    when (oldVersion) { 
     latestVersion -> return 
     1 -> upgradeFromV1() 
     2 -> upgradeFromV2() 
     3 -> upgradeFromV3() 
    } 
    upgrade(oldVersion + 1) 
} 
+0

के लिए विधि को कॉल करने के बजाय रिकर्सन का उपयोग कर सकते हैं [tailrec] (https://kotlinlang.org/docs/reference/functions.html#tail-recursive-functions) संशोधक (पुनरावर्ती रूप से) कहा जाता है) समारोह और आप सुनहरे हो! – Jerzyna

+0

@ जेर्जिना ने मेरे वर्तमान समाधान में संपादित किया, जो मेरी राय में थोड़ा सा अच्छा है। –

0

यहाँ, bashor से दो जवाब का एक मिश्रण है कार्यात्मक चीनी का एक छोटा सा के साथ: offisial संदर्भ से

fun upgradeFromV0() {} 
fun upgradeFromV1() {} 
fun upgradeFromV2() {} 
fun upgradeFromV3() {} 

val upgrades = arrayOf(::upgradeFromV0, ::upgradeFromV1, ::upgradeFromV2, ::upgradeFromV3) 

fun upgradeFrom(oldVersion: Int) { 
    upgrades.filterIndexed { index, kFunction0 -> oldVersion <= index } 
      .forEach { it() } 
} 
0

यह absolutly संभव है बोली https://kotlinlang.org/docs/reference/control-flow.html

If many cases should be handled in the same way, the branch conditions may be combined with a comma: 

when (x) { 
    0, 1 -> print("x == 0 or x == 1") 
    else -> print("otherwise") 
} 

तो यदि समान स्थिति सूची कम है, तो आप उन्हें कोमा द्वारा अलग करने की सूची दे सकते हैं, या अन्य उत्तरों में बताए गए अनुसार 1.10 की स्थिति जैसे श्रेणियों का उपयोग कर सकते हैं

+0

ओपी की समस्या के साथ यह कैसे मदद करता है? – melpomene

+0

इस उत्तर के लिए धन्यवाद। हालांकि यह सीधे सवाल का जवाब नहीं देता है, यह विभिन्न मामलों को संभालने के संबंधित प्रश्न का उत्तर देता है उसी तरह – TheIT

+0

इस उत्तर ने मेरी मदद की :), धन्यवाद। – moxi

0

ओपी के जवाब का एक और भिन्नता:

override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { 
    when (oldVersion) { 
     newVersion -> return 
     1 -> TODO("upgrade from v1") 
     2 -> TODO("upgrade from v2") 
    } 
    onUpgrade(db, oldVersion,newVersion) 
} 
-1
val orders = arrayListOf(
      { upgradeFromV1()}, 
      { upgradeFromV2()}, 
      { upgradeFromV3()} 
) 

orders.drop(oldVersion).forEach { it() } 
संबंधित मुद्दे