gpt4 book ai didi

java - 在 'is' 类型检查后的 When Expression 中进行智能转换和比较

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:34:02 25 4
gpt4 key购买 nike

根据 When Expression 的文档,它可以替换“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 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
}

上面的实现可行,但我认为它可以更简洁:

fun maxOf(a: Any, b: Any) = 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
}

但是我失败了,因为第二个实现不起作用;错误出现在第一次出现 if (a < b) 时:

Unresolved references.

None of the following candidates is applicable because of receiver type mismatch

public fun String.compareTo(other: String, ignoreCase: Boolean =...): Int defined in kotlin.text

这是因为 smart-cast 无法转换 ab在计算表达式 (a is Int || a is Double) && (b is Int || b is Double) 后转换为它们的实际类型?还是我遗漏了什么?

更新

即使 a 的类型也会发生同样的错误和 b更改为 Number :

fun maxOf(a: Number, b: Number) = when {
(a is Int || a is Double) && (b is Int || b is Double) -> if (a < b) b else a
else -> null
}

最佳答案

为什么会这样?

这不是when的问题表达。你应该责怪类型系统。

abInt 的实例和 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

然而,IntDoubleNumber 的子类和 Comparable同时,Kotlin 不知道你是否想要 NumberComparable ,因此 Kotlin 将其视为 Any 的一个实例.

if (a is Int || a is Double)
if (a > 1) print("meow meow") // smart cast doesn't work

这就是“错误”出现的原因。

如何解决这个问题?

使用您的原始代码,或使用显式转换(我知道这很糟糕,但它确实是一个不可避免的问题)。

我想出了一个漂亮的解决方案!看看它:

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
}

通过这种方式,您可以应用任何 Comparable到它(而不是 IntDoubleString )!

fun <T : Comparable<T>> maxOf(a: T, b: T): T = if (a < b) b else a

您的原始版本将返回 null如果输入无效,此版本会在输入无效时引发编译错误,帮助您在编译时发现错误。

提及!

您对我发表了评论并提出了进一步的问题。我想让我的回复更具可读性,所以我会将其添加到我的答案中。

fun someFunction(a: Number) {
if (a is Int || a is Double) println(a < 1) // still error! Why?!
}

是的,的确如此,aNumber 的实例这里。但请务必提及,< , 或者, compareTo , 未在 Number 中声明 .它在 IntDouble :).

编辑2

你说:

using generics forces a and b to be the same type.

那么试试这个:

fun <A : Comparable<B>, B : Any> maxOf(a: A, b: B): Any = if (a < b) b else a

你说:

explicit cast is not a solution if the type of a and b is Any

  • 解决方案零:创建operator fun Any.compareTo
  • 解决方案一:放弃类型转换。

关于java - 在 'is' 类型检查后的 When Expression 中进行智能转换和比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47117014/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com