代码之家  ›  专栏  ›  技术社区  ›  Anthony

Kotlin[1..n]构造函数参数

  •  1
  • Anthony  · 技术社区  · 4 年前

    我试过:

    class Permission(
        // 1..n compliance
        accessiblePage: Webpage,
        vararg accessiblePages: Webpage
    ) {
    

    但这也意味着 Permission(*pages)

    有没有一种简单的方法可以在没有运行时构造函数错误的情况下执行1..*?

    0 回复  |  直到 4 年前
        1
  •  0
  •   Rohen Giralt    4 年前

    不幸的是,除了您提到的方法之外,没有其他方法可以在编译时在Kotlin中检查这一点。由于vararg参数实际上只是数组的语法糖,因此您的代码本质上是

    class Permission (
        accessiblePage: Webpage,
        accessiblePages: Array<Webpage>
    )
    

    所以问题就变成了“你能保证数组在编译时至少有一个元素吗?”对于大多数语言来说,这是一个明显的否定,尽管Kotlin团队曾经用它做过实验:

    集合大小。仅供参考,Kotlin团队曾试图收集 信息,并用于警告可能的 IndexOutOfBoundException之类的东西,但是发现 在现实生活中,对这种诊断的需求很少 因此,考虑到这种分析的复杂性,它被放弃了 ( https://github.com/Kotlin/KEEP/issues/139#issuecomment-405551324

    有可能在某个时候会添加此元数据,但您不应该期望很快就会添加。

    也就是说,对于数组,您总是可以将运行时检查与对于varargs的重载签名结合起来。这意味着您的vararg示例的工作原理相同,但是将数组传递给函数将使其接受运行时检查(您也不必再使用spread操作符):

    class Permission (
       accessiblePage: Webpage
       vararg accessiblePages: Webpage
    ) {
        constructor(accessiblePages: Array<Webpage>) {
            require(accessiblePages.isNotEmpty()) {
                "Must have at least one accessible page."
            }
        }
    }
    

    叫得像

    val permission1 = Permission(Webpage(), Webpage())
    val permission2 = Permission() // Would fail at compile time
    
    val pages = arrayOf()
    val permission3 = Permission(pages) // Would fail at runtime. Note also the lack of the spread operator.