设计弃用警告以将列表替换为 vararg

Design deprecation warning to replace a list with vararg

提问人:vatbub 提问时间:10/20/2023 更新时间:10/21/2023 访问量:50

问:

我有以下方法:

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

因此,我添加了一个注释,建议调用者使用该版本,但如果用例实际上是合法的,则很容易被抑制。@DeprecatedRowVector(elements: List<Double>)vararg

我面临的问题是注释部分的设计。我希望IDE替换为,但到目前为止,我还没有找到一种方法来做到这一点:ReplaceWith@DeprecatedRowVector(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 类型推理 用警告

评论


答:

1赞 Endzeit 10/21/2023 #1

可悲的是,这很可能是不可能的。

在您的示例中,您直接在函数调用中声明 。但是,这不是调用函数的唯一方法。List<Double>

例如,我可以先将内部声明为 ue。Listval

val foo = listOf(0.0)
RowVector(foo)

如果您能够声明一个替换项,该替换项将从提供的值中提取值,则 IDE 实际上需要内联声明,这可能会改变行为。ReplaceWithList

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

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

RowVector(fooFun())

由于此代码的结果(几乎)是随机的,因此我看不出替换在这里如何工作。

就个人而言,在这种情况下,我会完全省略,而是提供有关如何正确手动更改代码的线索。ReplaceWithmessage

评论

1赞 vatbub 10/22/2023
您提到的情况正是对 -variant 的调用是合法的,但是在我的经验中,它们似乎相当罕见,而直接通过调用声明值的情况似乎更常见。无论哪种方式,我现在都只发了一条消息。干杯:)ListlistOf