2016-09-21 38 views
5

Bir tür bir ifade şöyle eğer bir başka türe uygun olup olmadığını kontrol etmek çalışıyorum. Bu hata hakkında ayrıntılı bilgi veren ve/veya bu kontrolü nasıl yapmam gerektiğini söyleyen var mı?Kotlin sınıfında boş sol taraftaki hazır bilgiler henüz desteklenmiyor mu?</p> <pre><code>if (String::class is Any::class) </code></pre> <p>Bu bana boş sol tarafı hata sınıfı değişmezleri verir henüz desteklenmez:

düzenleme (açıklama): Eşitlik kontrolü yapamıyorum çünkü soldaki sınıfa ait sınıfın sağdaki sınıfla mı eşleştiğini mi yoksa bir alt sınıf mı olduğunu bilmem gerekiyor. Öyleyse soldaki sınıfın bir örneği sağdaki sınıfa güvenli bir şekilde dökülebilir.

if ("A string" is Any) 

Ama bir dize örneği kalmadan

, dize sadece burada bir örnek kullanılıyor:

Temelde ben eşdeğeri gerekir.

+0

Bunu yapmanın hiçbir yolu ve tek yol Java yansımasını kullanmaktır (JVM'yi hedeflediğiniz varsayılarak). http://stackoverflow.com/questions/35851719/how-to-compare-classes-and-interfaces/35852445#35852445 – zjuhasz

cevap

3

Kişisel hata mesajı is çek bir beklediğini olduğunu sınıf adı ve sağ taraftaki bir KClass'a bir başvuru değil. Mesajın kendisi biraz belirsiz olabilir. Fakat aynısı Java'da da geçerlidir, instanceOf operatörünü kullanmazsınız, bunun yerine isAssignableFrom'u çağırırsınız. problem çözme konusunda yardım için

, sen Github bulunabilir örnekler ... Klutter libraryType ve KType olarak, KClass, Class arasındaki kontrol InstanceOf tarzı kombinasyonları bir sürü örnekleridir yılında

var ilkel olarak. Fikirleri oradan kopyalayabilirsiniz. Uzun vadede ele almak isteyebileceğiniz birçok kombinasyon var.

Bir türün diğerinden atanıp atanmadığını denetlemek için a big mix of extensions örneklemi. Birkaç örnek:

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'a bakın.

Ve yukarıdaki örneklerin tarafından kullanılan bu erasedType() extension gerekir - bir Class (tip sonra silme) geri bir Type gider: Meslektaşım Kotlin söylüyor başka SO yazı bulundu

@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

Eğer Kotlin'in bir KClass ve başka bir KClass arasında bir operatör ile farklı bir KClass arasında farklı bir şekilde kullanıldığını açıklığa kavuşturabilirim. Her neyse, bu küçük infix fonksiyonunu işlevselliği taklit ettim. Ancak, Java yansımasını kullandığı için sadece JVM hedefi ile çalışır. Bu answer given in this SO post'dan çıkıyor.

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

Bu benim yapmaya çalıştığım tam olarak ne yapmak için izin ancak yerine kutu fonksiyonu ile şöyle operatörüdür olacaktır:

if(String:class can Any::class)