2016-09-21 7 views
5

私はそうのような式ならば型が持つ別の型に適合しているかどうかを確認しようとしています:これは、空の左手側とエラークラスリテラルはまだサポートされていない私に与え左の空のKotlinクラスリテラルはまだサポートされていませんか?

if (String::class is Any::class) 

。誰もがそのエラーを詳しく説明したり、このチェックをどのようにしなければならないか教えてください。

edit(説明):左のクラスが右のクラスと一致するか、それともそのサブクラスかを知る必要があるため、等価チェックはできません。したがって、左側のクラスのインスタンスが右側のクラスに安全にキャストできれば。

基本的に私は相当必要があります。

if ("A string" is Any) 

をしかし、Stringインスタンスを持たずに、文字列はちょうどここに例を使用しています。

+0

これを行う方法はなく、唯一の方法はJavaリフレクションを使用することです(JVMをターゲットにしていると仮定します)。 http://stackoverflow.com/questions/35851719/how-to-compare-classes-and-interfaces/35852445#35852445 – zjuhasz

答えて

3

あなたのエラーメッセージがisチェックが期待されていることクラス名であり、右側のKClassへの参照ではありません。メッセージ自体は少し不明かもしれません。しかし、Javaでも同じことが言えますが、instanceOf演算子は使用せず、代わりにisAssignableFromを呼び出します。

問題を解決するためのヘルプについては、あなたはGitHubの中に見つけることができる例を持っている... Klutter library

ClassKClassTypeKTypeなどの間INSTANCEOFスタイルチェックの組み合わせの多くの例であり、プリミティブと同じように。そこからアイデアをコピーすることができます。あなたが長期的にカバーしたかったかもしれない多くの組み合わせがあります。

ここでは、一方のタイプが他方から割り当て可能かどうかをチェックするための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が必要になります - (型消去後)バックClassからTypeから行きた:私の同僚はKotlinが持っていると言い、別のSOのポストを見つけ

@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

KotlinがisClassと別のKClassを別々に使用していたのは、インスタンスとタイプの間でやっているように、私がやっていることがうまくいかないため、明らかではないでしょう。とにかく、私はこの小さなインフィックス関数を使ってその機能を模倣しました。しかし、それはJavaリフレクションを使用しているので、もちろん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) 
関連する問題