为什么Kotlin中Array.reduce的返回值存在类型限制,不能为任意类?
首先明确结论:这个类型约束是reduce API的固有设计,不是无意义的限制,你遇到的报错本质是用错了API。
为什么reduce有T : S的约束
reduce的设计逻辑是不接收外部传入的初始值,它会把数组的第一个元素作为累加器的初始值,后续遍历剩余元素迭代计算。
所以类型参数要求T : S(数组元素类型T是累加器类型S的子类)是完全合理的:因为第一个元素类型为T,要能直接当作S类型的初始累加器使用,必须满足T可向上转型为S。
你的写法为什么报错
你调用reduce时传入了Args()作为初始值,而Kotlin标准库的reduce根本没有初始值的入参,属于API误用。
如果你需要自定义初始值、且返回值类型和数组元素类型无关,应该使用fold API:fold没有T : S的类型约束,支持返回任意类型,签名如下:
inline fun <S, T> Array<out T>.fold( initial: S, operation: (acc: S, T) -> S ): S
你的代码修改为fold即可正常运行:
fun main(params: Array<String>) { val args = params.fold(Args(), { accum: Args, arg: String -> accum.parse(arg) }) }
两个API的适用场景区分
- 累加结果类型和数组元素类型一致/是元素父类,不需要额外指定初始值,使用
reduce,例:求Int数组的总和、拼接字符串数组为完整字符串 - 需要自定义初始值,或结果类型与数组元素类型无继承关系,使用
fold
内容的提问来源于stack exchange,提问作者Huckle
相关产品推荐
相关产品推荐

