我有一个正则表达式的结果,该表达式将七个捕获组返回到一个数组中。
我认为我将使用解构,而不是使用数组元素的下标来构造我的对象,问题是似乎我只能有五个组件。
一个最小的例子:
// 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)
Run Code Online (Sandbox Code Playgroud)
编译器输出:
> 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
Run Code Online (Sandbox Code Playgroud)
有没有办法拥有五个以上的组件,或者这是最大值?
该List接口仅定义了5个组件功能(作为扩展功能)。
您可以添加自己的组件功能作为扩展功能:
operator fun <T> List<T>.component6() = this[5]
operator fun <T> List<T>.component7() = this[6]
// ...
Run Code Online (Sandbox Code Playgroud)
现在可以使用:
val (a, b, c, d, e, f, g) = listOf(1, 2, 3, 4, 5, 6, 7)
Run Code Online (Sandbox Code Playgroud)
从文档:
而且,当然可以有component3()和component4()等等。
请注意,componentN()函数需要用operator关键字标记,以允许在解构声明中使用它们。
Kotlin 为这些组件析构函数定义了扩展方法。与数据类不同,这些不是无限生成的,每个项目一个。这也使它们有点危险,我稍后会谈到。
作为参考,定义在这里,KDoc可以在这里找到(component在列表中搜索。为了方便访问,这里是component1)。
正如您在源定义(以及与此相关的文档,但源使其更加可见)中看到的那样,只有 5 个方法 ( component1to component5),每个方法都调用get(n - 1),其中n是组件析构函数的 ID。
如果您想要更多,则必须按照以下模式自己定义它们:
inline operator fun <T> List<T>.componentN(): T {
return get(N - 1)
}
Run Code Online (Sandbox Code Playgroud)
(或在另一个答案中建议的风格- 它们产生相同的结果。)
同样,其中 N 为 6 及以上,与您计划拥有的项目数量相匹配。
但是,我不会推荐这个。使用 for 循环对其进行迭代要容易得多,而且也不太容易出错。以这样的例子为例:
val (a, b, c, d, e) = listOf(1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)
这将抛出一个 ArrayIndexOutOfBoundsException。但是,如果您有一个静态列表(并且知道您在做什么),则使用 with 进行破坏componentN是安全的。尽管如果您有一个主要是静态的列表,并且希望在未来获得灵活性,则可以使用数据类。这些也componentN为您生成函数,并将它们自己限制在您实际拥有的字段数量 - 这意味着在运行时没有异常,而是编译器错误。
如果您使用列表来启用除销毁之外的迭代,您还可以采用替代方法并定义一个operator fun iterator并返回项目列表。
| 归档时间: |
|
| 查看次数: |
178 次 |
| 最近记录: |