2016-09-21 6 views
5

मैं अगर एक प्रकार एक यदि ऐसा है तो तरह अभिव्यक्ति के साथ एक एक अन्य प्रकार के अनुरूप है की जाँच करने की कोशिश कर रहा हूँ। क्या कोई उस त्रुटि पर विस्तार कर सकता है और/या मुझे बता सकता है कि मुझे यह जांच कैसे करनी चाहिए?खाली बाएं हाथ के साथ कोटलिन वर्ग अक्षर अभी तक समर्थित नहीं हैं?</p> <pre><code>if (String::class is Any::class) </code></pre> <p>यह मैं खाली बाएं हाथ की ओर से त्रुटि वर्ग शाब्दिक देता है अभी तक समर्थित नहीं हैं:

संपादित करें (स्पष्टीकरण): मैं समानता जांच नहीं कर सकता क्योंकि मुझे पता होना चाहिए कि बाईं ओर की कक्षा या तो दाईं ओर कक्षा से मेल खाती है या इसका उप-वर्ग है। तो यदि बाईं ओर कक्षा का एक उदाहरण सुरक्षित रूप से दाईं ओर कक्षा में डाला जा सकता है।

if ("A string" is Any) 

लेकिन एक स्ट्रिंग उदाहरण बिना, स्ट्रिंग बस यहाँ एक उदाहरण इस्तेमाल किया जा रहा:

मूल रूप से मैं के बराबर की जरूरत है।

+0

मेरे सहयोगी एक और एसओ पद जो कहते हैं Kotlin है पाया ऐसा करने का कोई तरीका नहीं है और जावा प्रतिबिंब का उपयोग करने का एकमात्र तरीका है (मान लें कि आप JVM को लक्षित कर रहे हैं)। http://stackoverflow.com/questions/35851719/how-to-compare-classes-and-interfaces/35852445#35852445 – zjuhasz

उत्तर

3

आपका त्रुटि संदेश जाता है कि is जांच एक उम्मीद कक्षा का नाम और दाईं तरफ KClass का संदर्भ नहीं है। संदेश स्वयं थोड़ा अस्पष्ट हो सकता है। लेकिन जावा में भी यही लागू होता है, आप instanceOf ऑपरेटर का उपयोग नहीं करेंगे बल्कि इसके बजाय isAssignableFrom पर कॉल करेंगे।

समस्या को हल करने में मदद के लिए, आप

में Klutter library instanceof शैली,, Class के बीच KClassType और KType के रूप में जाँच के संयोजन का एक बहुत के उदाहरण हैं Github में पाया जा सकता है कि उदाहरण ... है प्राइमेटिव के रूप में अच्छी तरह से। आप वहां से विचारों की प्रतिलिपि बना सकते हैं। ऐसे कई संयोजन हैं जिन्हें आप लंबे समय तक कवर करना चाहते हैं।

यह जांचने के लिए a big mix of extensions का एक नमूना है कि एक प्रकार दूसरे से असाइन करने योग्य है या नहीं। कुछ उदाहरण हैं:

fun <T : Any, O : Any> KClass<T>.isAssignableFrom(other: KClass<O>): Boolean { 
    if (this.java == other.java) return true 
    return this.java.isAssignableFrom(other.java) 
} 

fun <T : Any> KClass<T>.isAssignableFrom(other: Class<*>): Boolean { 
    if (this.java == other) return true 
    return this.java.isAssignableFrom(other) 
} 

fun KClass<*>.isAssignableFromOrSamePrimitive(other: KType): Boolean { 
    return (this.java as Type).isAssignableFromOrSamePrimitive(other.javaType) 
} 

fun KClass<*>.isAssignableFromOrSamePrimitive(other: Type): Boolean { 
    return (this.java as Type).isAssignableFromOrSamePrimitive(other) 
} 

fun Type.isAssignableFromOrSamePrimitive(other: Type): Boolean { 
    if (this == other) return true 
    if (this is Class<*>) { 
     if (other is Class<*>) { 
      return this == other.kotlin.javaObjectType || this == other.kotlin.javaPrimitiveType || 
        this.isAssignableFrom(other) 
     } 
     return this.isAssignableFrom(other.erasedType()) 
    } 
    return this.erasedType().isAssignableFrom(other.erasedType()) 
} 

// ... and so on for every permutation of types 

linked source for all permutations देखें।

और आप इस erasedType() extension ऊपर नमूने द्वारा इस्तेमाल किया की आवश्यकता होगी - जो एक Type पीछे से एक Class (प्रकार के बाद विलोपन) को जाता है:

@Suppress("UNCHECKED_CAST") fun Type.erasedType(): Class<Any> { 
    return when (this) { 
     is Class<*> -> this as Class<Any> 
     is ParameterizedType -> this.getRawType().erasedType() 
     is GenericArrayType -> { 
      // getting the array type is a bit trickier 
      val elementType = this.getGenericComponentType().erasedType() 
      val testArray = java.lang.reflect.Array.newInstance(elementType, 0) 
      testArray.javaClass 
     } 
     is TypeVariable<*> -> { 
      // not sure yet 
      throw IllegalStateException("Not sure what to do here yet") 
     } 
     is WildcardType -> { 
      this.getUpperBounds()[0].erasedType() 
     } 
     else -> throw IllegalStateException("Should not get here.") 
    } 
} 
4

मुझे लगता है कि यह स्पष्ट नहीं होगा अगर कोटलिन ने केक्लास और अन्य केक्लास के बीच अलग-अलग ऑपरेटर का उपयोग किया था, क्योंकि यह एक उदाहरण और एक प्रकार के बीच होता है, यही कारण है कि मैं जो करने की कोशिश कर रहा था वह काम नहीं करता है। वैसे भी मैंने कार्यक्षमता की नकल करने के लिए इस छोटे इंफिक्स फ़ंक्शन को बनाया है। हालांकि यह केवल जावा प्रतिबिंब का उपयोग कर रहा है क्योंकि यह केवल JVM लक्ष्य के साथ काम करता है। यह answer given in this SO post से बाहर जा रहा है।

infix fun <T : Any, C : Any> KClass<T>.can(comparate: KClass<C>) = 
    comparate.java.isAssignableFrom(this.java) 

यह आपको वास्तव में मैं क्या करने की कोशिश कर रहा था करने की अनुमति देगा, लेकिन के बजाय कर सकते हैं समारोह के साथ ऐसा जैसे ऑपरेटर है:

if(String:class can Any::class) 
संबंधित मुद्दे