Based on this answer
I wanted to create an infix version of a function which checks a variable type.
However, it seems to be ignored by the compiler. Please see the example code:
@OptIn(ExperimentalContracts::class)
inline infix fun <SELF, reified TYPE : Class<out Any>> SELF.isType(type: TYPE): Boolean {
contract { returns(true) implies (this@isType is TYPE) }
return type.isInstance(this)
}
fun demo() {
// we know it can be only String
val someValue: Any = if (System.currentTimeMillis() <= 1) 12345 else "some-string"
val someType = String::class.java
// I would expect that [isInstance] implies a type inside the "if" block, but it doesn't.
// Without "as String" it's a compile error.
if (someType.isInstance(someValue)) {
println("length is " + (someValue as String).length)
}
// That's why I want to create a custom infix function "isType" with Kotlin contracts.
// But still, without "as String" it's a compile error.
if (someValue isType someType) {
println("length is " + (someValue as String).length)
}
}
What could be the problem there?
There are two reasons for this.
First, you made a mistake in your code. You say
someValueis aTYPE, butTYPEisClass<String>. Even if your smart cast worked correctly, you castsomeValuetoClass<String>and you planned to cast it toString. Fixed code:Second, apparently, there is a bug in the Kotlin compiler and smart casts don't work if using the infix syntax: