设计弃用警告,用 vararg 替换列表

问题描述 投票:0回答:1

我有以下方法:

fun RowVector(x: Double, y: Double): RowVector2 = RowVector(listOf(x, y)) as RowVector2
fun RowVector(x: Double, y: Double, z: Double): RowVector3 = RowVector(listOf(x, y, z)) as RowVector3
fun RowVector(vararg elements: Double): RowVector = RowVector(elements.asList())

fun RowVector(elements: List<Double>): RowVector = // Actually creates the RowVector instance

虽然有一些合法的用例可以调用

RowVector(elements: List<Double>)
,但我想鼓励调用者使用该方法的
vararg
版本,因为这允许编译器进行一些更智能的类型推断,如下所示:

val vector1 = RowVector(listOf(0.0, 1.0, 2.0)) // Type is inferred to be RowVector
val vector2 = RowVector(0.0, 1.0, 2.0) // Compiler can see that only 3 values are passed and therefore infers RowVector3

因此,我在

@Deprecated
中添加了
RowVector(elements: List<Double>)
注释,建议调用者宁愿使用
vararg
版本,但如果用例实际上是合法的,则很容易被抑制。

我面临的问题是

ReplaceWith
注释的
@Deprecated
部分的设计。我希望 IDE 将
RowVector(listOf(0.0, 1.0, 2.0))
替换为
RowVector(0.0, 1.0, 2.0)
,但到目前为止,我还没有找到方法来做到这一点:

@Deprecated(
    "Prefer the vararg interface if possible as it allows the compiler to infer types better.",
    ReplaceWith("RowVector(*elements.toDoubleArray())")
)

导致

RowVector(*listOf(0.0, 1.0, 2.0).toDoubleArray())
,仍然需要手动清理。

@Deprecated(
    "Prefer the vararg interface if possible as it allows the compiler to infer types better.",
    ReplaceWith("RowVector(*doubleArrayOf(elements))")
)

奇怪的是什么也没做并且

@Deprecated(
    "Prefer the vararg interface if possible as it allows the compiler to infer types better.",
    ReplaceWith("RowVector(*elements)")
)

进行字面替换,如下所示:

RowVector(*listOf(0.0, 1.0, 2.0))

我知道这是一个第一世界的问题,调用者只需阅读警告并轻松删除

listOf()
,但我仍然会尽力让调用者尽可能简单。

kotlin type-inference deprecation-warning
1个回答
0
投票

遗憾的是,这很可能是不可能的。

在您的示例中,您直接在函数调用内声明

List<Double>
。然而,这并不是调用该函数的唯一方法。

例如,我可以先在

List
ue 中声明
val

val foo = listOf(0.0)
RowVector(foo)

如果您能够使用

ReplaceWith
声明替换,从而从提供的
List
中提取值,则 IDE 实际上需要内联该声明,这可能会改变行为。

此外,

List
可能是函数调用的结果,这会使自动替换更加成问题。

val random = Random()
fun fooFun() = List(random.nextInt(0, Int.MAX_VALUE)) { random.nextDouble() }

RowVector(fooFun())

由于此代码的结果(几乎)是随机的,我不知道替代品如何在这里工作。

就我个人而言,在这种情况下我会完全省略

ReplaceWith
,而是提供一个很好的
message
,其中包含有关如何正确手动更改代码的线索。

© www.soinside.com 2019 - 2024. All rights reserved.