Java 在';是';类型检查
根据的文档,它可以替换“if-else-if”,因此我尝试实现一个函数,最多返回两个Java 在';是';类型检查,java,kotlin,Java,Kotlin,根据的文档,它可以替换“if-else-if”,因此我尝试实现一个函数,最多返回两个Any类型的变量: fun maxOf(a: Any, b: Any) = when { a is Int && b is Int -> if (a < b) b else a a is Double && b is Double -> if (a < b) b else a a is Int && b
Any
类型的变量:
fun maxOf(a: Any, b: Any) = when {
a is Int && b is Int -> if (a < b) b else a
a is Double && b is Double -> if (a < b) b else a
a is Int && b is Double -> if (a < b) b else a
a is Double && b is Int -> if (a < b) b else a
a is String && b is String -> if (a < b) b else a
else -> null
}
为什么会这样?
这不是表达时的问题。你应该归咎于类型系统
a
和b
是Int
和Double
的实例,因此Kotlin将推断它们为LCA。例如:
open class A { fun a() = println("meow meow meow") }
class B : A()
class C : A()
if (a is B || a is C) a.a() // smart cast works
但是,
Int
和Double
同时是Number
和Comparable
的子类,Kotlin不知道您想要的是Number
还是Comparable
,因此Kotlin将其视为Any
的实例
if (a is Int || a is Double)
if (a > 1) print("meow meow") // smart cast doesn't work
这就是“bug”出现的原因
如何解决这个问题?
使用您的原始代码,或者使用显式转换(我知道它很糟糕,但它确实是一个不可避免的问题)
我想出了一个漂亮的解决办法!看看它:
fun <T : Comparable<T>> maxOf(a: T, b: T): T? = when {
(a is Int || a is Double) && (b is Int || b is Double) -> if (a < b) b else a
a is String && b is String -> if (a < b) b else a
else -> null
}
如果输入无效,原始版本将返回null
,如果输入无效,此版本将引发编译错误,帮助您在编译时查找错误
提到!
你对我发表了评论,并问了一个进一步的问题。我想让我的回答更具可读性,所以我会将其添加到我的答案中
fun someFunction(a: Number) {
if (a is Int || a is Double) println(a < 1) // still error! Why?!
}
你说:
如果a
和b
的类型为Any
- 解决方案零:创建
运算符fun Any.compareTo
- 解决方案一:放弃铸造
Int
和Double
是数字
和可比
的子类……Kotlin将其视为任何
的一个实例”,您在回答中提到。但是,如果我强制aa
成为一个Number
,以下仍然不起作用:funprintmeow(a:Number){if(a是Int | | a是Double)if(a>1)print(“meow”)}
,所以我不太确定这是不是真的。编辑并回答了你的问题。嘿!我刚刚想出了一个非常漂亮的解决方案,请看一看!我现在觉得自己非常聪明:至少smart cast足够聪明,可以知道类型T
与T
相同,并进行比较。这不是smart cast的工作。这是泛型。你为什么不使用Comparable?@njzk2你能更具体一点吗?nvm,这不适用于比较整数和双倍数
fun <T : Comparable<T>> maxOf(a: T, b: T): T? = when {
(a is Int || a is Double) && (b is Int || b is Double) -> if (a < b) b else a
a is String && b is String -> if (a < b) b else a
else -> null
}
fun <T : Comparable<T>> maxOf(a: T, b: T): T = if (a < b) b else a
fun someFunction(a: Number) {
if (a is Int || a is Double) println(a < 1) // still error! Why?!
}
fun <A : Comparable<B>, B : Any> maxOf(a: A, b: B): Any = if (a < b) b else a