我有以下方法:

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

因此,我在RowVector(elements: List<Double>)中添加了@Deprecated注释,它建议调用者使用vararg版本,但如果用例实际上是合法的,则可以很容易地将其取消.

我面临的问题是@Deprecated注释的ReplaceWith部分的设计.我希望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(),但我还是会尽可能让打电话的人容易.

推荐答案

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

在您的示例中,您直接在函数调用中声明了List<Double>.然而,这并不是调用该函数的唯一方式.

例如,我可以先声明value内的List.

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,它提供了如何正确手动更改代码的线索.

Kotlin相关问答推荐

Kotlin-删除按钮周围的空格

在Mapstruct中重用@映射定义

Kotlin 海峡没有结束

如何在Spring Boot中注册新的集合工厂

如何定义一个函数来接受任何具有特定字段的数据类

如何检测一个值是否是Kotlin中的枚举实例?

Kotlin 中的as Long和.toLong()有什么区别?

Kotlin 使用委托进行隐式覆盖

使用 Discord4j 交叉发布 Discord 消息

是什么让 Kotlin 中的 String 类能够使用方括号?

Kotlin:查找集合中最常见的元素

Kotlin RxJava 可空的错误

在 Kotlin 中,当枚举类实现接口时,如何解决继承的声明冲突?

Kotlin:泛型、反射以及类型 T 和 T:Any 之间的区别

Kotlin:什么是 kotlin.String!类型

Kotlin惰性默认属性

将多个 Kotlin 流合并到一个列表中,而无需等待第一个值

在 suspendCoroutine 块中调用挂起函数的适当方法是什么?

在Kotlin中将列表转换为对的惯用方法

如何在不绑定ViewModel(MVVM)中的UI的情况下使用android导航?