Kotlin破坏了五个以上的组成部分

时间:2019-04-28 13:57:15

标签: kotlin

我得到了一个正则表达式的结果,该表达式将七个捕获组返回到一个数组中。

问题是我似乎只能使用五个组件,而不是使用数组元素的下标来构造对象,我以为我会使用解构。

一个最小的例子:

//  val (a, b, c, d, e) = listOf(1, 2, 3, 4, 5)
val (a, b, c, d, e, f, g) = listOf(1, 2, 3, 4, 5, 6, 7)

编译器输出:

> Error:(70, 41) Kotlin: Destructuring declaration initializer of type
> List<Int> must have a 'component6()' function 
> Error:(70, 41) Kotlin: Destructuring declaration initializer of type 
> List<Int> must have a 'component7()' function

有没有办法拥有五个以上的组件,或者这是最大值?

2 个答案:

答案 0 :(得分:4)

List接口仅定义了5个组件功能(作为扩展功能)。

您可以添加自己的组件功能作为扩展功能:

operator fun <T> List<T>.component6() = this[5]
operator fun <T> List<T>.component7() = this[6]
// ...

现在可以使用:

val (a, b, c, d, e, f, g) = listOf(1, 2, 3, 4, 5, 6, 7)

来自docs

  

当然,可以有component3()和component4()等等。

     

请注意,componentN()函数需要用   运算符关键字,以允许在解构声明中使用它们。

答案 1 :(得分:3)

Kotlin为这些组件析构函数定义了扩展方法。与数据类不同,它们不会无限生成每个项目一个。这也使它们有些危险,我稍后再讲。

供参考,定义为here,可以找到here(在列表中搜索component。为便于访问,请访问component1),找到KDoc。

正如您在源代码定义(以及相关文档中看到的,但源代码使它更加可见)中所看到的那样,只有5种方法(component1component5),每个方法都调用get(n - 1),其中n是组件析构函数的ID。

如果需要更多,则必须按照以下方式自己定义它们:

inline operator fun <T> List<T>.componentN(): T {
    return get(N - 1)
}

(或采用the other answer中建议的样式-它们产生相同的结果。)

同样,N等于6或更高,与您计划拥有的物品数量匹配。

但是,我不建议这样做。使用for循环对其进行迭代要容易得多,并且也不太容易出错。以这个为例:

val (a, b, c, d, e) = listOf(1, 2, 3, 4)

这将引发ArrayIndexOutOfBoundsException。但是,如果您有一个静态列表(并且知道自己在做什么),那么使用componentN进行销毁是安全的。尽管如果您的列表大部分是静态的,并且希望将来具有更大的灵活性,则可以使用数据类。它们还会为您生成componentN函数,并将自身限制为实际拥有的字段数量-这意味着运行时不会出现异常,而是编译器错误。

如果使用列表除破坏之外还启用迭代,则还可以采用替代方法并定义operator fun iterator并返回项目列表。