如何强制调用某些构造函数/函数以使用命名参数?

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

我有一些构造函数和函数,我希望始终使用命名参数来调用它们。有没有办法要求这个?

我希望能够对具有许多参数的构造函数和函数以及那些在使用命名参数时读得更清楚的构造函数和函数执行此操作,等等。

kotlin named-parameters
2个回答
38
投票

在 Kotlin 1.0 中,您可以使用 stdlib 中的

Nothing
来完成此操作。

在 Kotlin 1.1+ 中,您将得到“禁止的可变参数类型:Nothing”,但您可以通过使用私有构造函数(如

Nothing
)定义自己的空类来复制此模式,并将其用作第一个可变参数参数。

/* requires passing all arguments by name */
fun f0(vararg nothings: Nothing, arg0: Int, arg1: Int, arg2: Int) {}
f0(arg0 = 0, arg1 = 1, arg2 = 2)    // compiles with named arguments
//f0(0, 1, 2)                       // doesn't compile without each required named argument

/* requires passing some arguments by name */
fun f1(arg0: Int, vararg nothings: Nothing, arg1: Int, arg2: Int) {}
f1(arg0 = 0, arg1 = 1, arg2 = 2)    // compiles with named arguments
f1(0, arg1 = 1, arg2 = 2)           // compiles without optional named argument
//f1(0, 1, arg2 = 2)                // doesn't compile without each required named argument

它在 Kotlin 1.7 中也可以使用

Nothing
,但有必要抑制编译错误:

...
@Suppress("FORBIDDEN_VARARG_PARAMETER_TYPE", "UNUSED_PARAMETER")
vararg nothings: Nothing,
...

由于

Array<Nothing>
在 Kotlin 中是非法的,因此无法创建
vararg nothings: Nothing
的值来传递(我认为缺乏反射)。这看起来有点像黑客,我怀疑字节码中对于
Nothing
类型的空数组有一些开销,但它似乎有效。

此方法不适用于无法使用

vararg
的数据类主构造函数,但可以将其标记为
private
,并且辅助构造函数可以与
vararg nothings: Nothing
一起使用。


0
投票

虽然您无法在较新版本的 Kotlin 中将

Nothing
用作
vararg
类型,但您仍然可以使用
Unit

fun resize(vararg nothing: Unit, width: Int, height: Int) {
    // ...
}


resize(width = 100, height = 200)

不幸的是,与

Nothing
不同,从技术上讲,您可以传递此参数的值:

resize(Unit, Unit, width = 100, height = 200)

我个人认为它看起来“错误”,调用者会知道不要这样做,所以如果您不想为此目的创建一个特殊的不可实例化的类,这可能是一个更简单的选择。

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