Kotlin中如何为泛型Point类的ClosedRange实现自定义Iterator
问题1:iterator扩展函数报
unresolved reference T的解决方法 报错的核心原因是你在扩展函数中使用了泛型参数T,但没有在函数声明处显式声明这个泛型参数及对应的约束。需要注意你后续修正的函数返回值写的是Iterator<T>,这不符合逻辑:遍历Point区间返回的元素应该是Point对象,所以返回值要修正为Iterator<Point<T>>,正确声明如下:
operator fun <T> ClosedRange<Point<T>>.iterator(): Iterator<Point<T>> where T: Number, T: Comparable<T>
问题2:泛型Point的inc函数无法直接执行
+1操作的解决方法 Kotlin的Number抽象类没有统一的plus运算符重载,不同数字类型的加法逻辑、返回值类型都有差异,因此不能直接对泛型T类型的x、y执行加1操作,有两种常用的解决方案:
方案1:为常用的具体数字类型分别实现inc扩展(更推荐)
这种方案没有类型转换开销,逻辑清晰无安全隐患,示例如下:
// Int类型的Point自增实现 operator fun Point<Int>.inc(): Point<Int> = Point(x + 1, y + 1) // Double类型的Point自增实现 operator fun Point<Double>.inc(): Point<Double> = Point(x + 1.0, y + 1.0) // Long类型的Point自增实现 operator fun Point<Long>.inc(): Point<Long> = Point(x + 1L, y + 1L)
你可以根据自己实际使用的数字类型按需添加对应实现即可。
方案2:实现统一的泛型版inc函数
如果需要统一的泛型实现,可以通过类型判断分支处理不同数字类型,需要注意做好异常兼容,示例如下:
operator fun <T> Point<T>.inc(): Point<T> where T: Number, T: Comparable<T> { @Suppress("UNCHECKED_CAST") return when (x) { is Int -> Point(x + 1, y as Int + 1) as Point<T> is Long -> Point(x + 1L, y as Long + 1L) as Point<T> is Double -> Point(x + 1.0, y as Double + 1.0) as Point<T> is Float -> Point(x + 1f, y as Float + 1f) as Point<T> else -> throw UnsupportedOperationException("暂不支持${x::class.simpleName}类型的Point自增") } }
完整的iterator实现参考
operator fun <T> ClosedRange<Point<T>>.iterator(): Iterator<Point<T>> where T: Number, T: Comparable<T> = object : Iterator<Point<T>> { private var current = start override fun hasNext(): Boolean = current <= endInclusive override fun next(): Point<T> = current.apply { current = inc() } }
内容的提问来源于stack exchange,提问作者ntos
相关产品推荐
相关产品推荐

