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

Posted

技术标签:

【中文标题】如何强制调用某些构造函数/函数以使用命名参数?【英文标题】:How can I force calls to some constructors/functions to use named arguments? 【发布时间】:2016-09-20 12:39:24 【问题描述】:

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

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

【问题讨论】:

相关 Kotlin 错误:youtrack.jetbrains.com/issue/KT-14934 【参考方案1】:

在 Kotlin 1.0 中,您可以使用 stdlib 中的 Nothing 来做到这一点。

在 Kotlin 1.1+ 中,您将获得“Forbidden vararg parameter type: Nothing”,但您可以通过使用私有构造函数(如 Nothing)定义自己的空类并将其用作第一个 varargs 参数来复制此模式。

/* 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

由于 Array<Nothing> 在 Kotlin 中是非法的,因此无法创建 vararg nothings: Nothing 的值以传入(我想缺少反射)。不过,这似乎有点 hack,我怀疑 Nothing 类型的空数组的字节码中有一些开销,但它似乎可以工作。

这种方法不适用于不能使用vararg的数据类主构造函数,但可以将它们标记为private,辅助构造函数可以与vararg nothings: Nothing一起使用。

【讨论】:

虽然这不是语言设计的意图,但我为你的独创性喝彩:) 您可以使用 *arrayOf() 展开 Nothing 数组。或者你应该能够,我认为 @Deanveloper 我刚刚试了一下。我得到:“返回类型中不支持的 [Array 是非法的”和“不能使用 'Nothing' 作为具体类型参数”。即使可以,例如f0(*arrayOf<Nothing>(), 0, 1, 2) 中的后续参数也会与展开数组的内容相结合,这会导致不同的错误:“整数文字不符合预期的类型 Nothing”。 无法在 Kotlin 1.3.72 中工作,表示 vararg 没有任何禁止类型 @DimaRostopira 请参阅有关 1.1+ 的说明,我已在答案中将其向上移动以澄清,您需要创建自己的 Nothing 版本(您可以随便称呼它)我喜欢,例如Forbidden)

以上是关于如何强制调用某些构造函数/函数以使用命名参数?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 6种构造函数详解

使用可变参数但使用命名参数调用函数的 Scala 语法是啥?

Dart:Dart 如何匹配类的构造函数中的命名参数?

在函数调用中“使用严格”和命名参数

c++ 如何在构造函数中启动一个线程,从命名管道读取数据?

如何在 Dart 中调用超级构造函数?