我得到了一个正则表达式的结果,该表达式将七个捕获组返回到一个数组中。
问题是我似乎只能使用五个组件,而不是使用数组元素的下标来构造对象,我以为我会使用解构。
一个最小的例子:
// 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
有没有办法拥有五个以上的组件,或者这是最大值?
答案 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种方法(component1
至component5
),每个方法都调用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
并返回项目列表。