Java Kotlin:请求迭代器()的泛型方法和for循环
这是一个简单的通用方法,在for循环中传递args的值会导致一个错误,即: for循环范围必须具有和迭代器()方法Java Kotlin:请求迭代器()的泛型方法和for循环,java,generics,kotlin,Java,Generics,Kotlin,这是一个简单的通用方法,在for循环中传递args的值会导致一个错误,即: for循环范围必须具有和迭代器()方法 fun main(args:Array){ val arr:IntArray=intArrayOf(1,2,3,4) val charA:CharArray=charArrayOf('a','b','c','d')) 打印时间(arr) 印刷体(charA) } 有趣的printMe(args:T){ 用于(参数中的项目){ 打印项次(项目) } } 如何使它在char[]和ar
fun main(args:Array){
val arr:IntArray=intArrayOf(1,2,3,4)
val charA:CharArray=charArrayOf('a','b','c','d'))
打印时间(arr)
印刷体(charA)
}
有趣的printMe(args:T){
用于(参数中的项目){
打印项次(项目)
}
}
如何使它在
char[]
和array
的值之间进行迭代问题是编译器不知道您正在传递数组,并且T
可以是任何类型
解决此问题的一种方法是使用is
运算符:
fun <T>printMe(args: T){
if(args is Array<*>) {
for (items in args) {
println(items)
}
}
}
fun printMe(args:T){
if(args是数组){
用于(参数中的项目){
打印项次(项目)
}
}
}
这实际上有点微妙
关键问题是变量arr
的类型为IntArray
,而IntArray
不是从Array
派生的。类似地,IntArray
有一个iterator()
函数,但它不实现Iterable
对于CharArray
变量,也会发生同样的情况
事实上,IntArray
和CharArray
和Array
似乎除了any
之外没有任何公共基类或接口。因此,您要么传递对象并在printMe
中执行类型检查,要么使用重载
类型检查版本如下所示
printMe(args:Any) {
if(args is IntArray) {
for(item in args) {
println(item)
}
} else if (args is CharArray) {
for(item in args) {
println(item)
}
} else {
println("Not an IntArray or a CharArray")
}
}
重载看起来是这样的
printMe(args:IntArray) {
for(item in args) {
println(item)
}
}
printMe(args:CharArray) {
for(item in args) {
println(item)
}
}
IMO重载是一个更好的选择,因为你不能错误地传递一个不能处理的对象。Kotlin中的for loop按惯例工作,静态地寻找名为迭代器的操作符成员,它必须返回可以迭代的内容,即,依次具有操作员成员next
和hasNext
的对象
此类成员上的运算符
修饰符需要指定该成员满足某种约定,即迭代约定
由于args
属于T
类型,并且在每个可能的T
类型中都没有iterator
成员,因此不能轻易地对其进行迭代
但是,您可以为printMe
提供一个附加参数,该参数知道如何从T
的实例中获取迭代器,然后使用它获取迭代器并对其进行迭代:
fun main(args: Array<String>) {
val arr: IntArray = intArrayOf(1,2,3,4)
val charA: CharArray = charArrayOf('a','b','c','d')
printMe(arr, IntArray::iterator)
printMe(charA, CharArray::iterator)
}
fun <T> printMe(args: T, iterator: T.() -> Iterator<*>) {
for (item in args.iterator()) {
println(item)
}
}
fun main(args:Array){
val arr:IntArray=intArrayOf(1,2,3,4)
val charA:CharArray=charArrayOf('a','b','c','d'))
printMe(arr,IntArray::迭代器)
printMe(charA,CharArray::迭代器)
}
有趣的printMe(args:T,迭代器:T.()->迭代器){
for(args.iterator()中的项){
println(项目)
}
}
这里,T.()->迭代器
是一种表示。可以在T
上调用该类型的实例,就好像它们是它的扩展一样
此代码段之所以有效,是因为迭代器返回的自身有一个运算符扩展函数iterator.iterator()=This
,它只返回该迭代器,因此允许使用for循环遍历迭代器。这不起作用,因为IntArray和CharArray都不是数组。这是Java数组的不幸遗产。使用列表代替-它们基本上是一样的,但是使用正确的继承重载可能是最好的选择,但是我正在练习,我想知道事情是如何工作的。这很简单,但是我不喜欢将类型绑定到调用站点。感觉这太像printMe(arr.iterator)
了,其中printMe是由fun printMe(iterator:iterator)``给出的。@MichaelAnderson您也可以将printMe称为printMe(arr,{iterator()})
。我同意在这种情况下,您只需传递迭代器本身,但有时您可能需要在printMe
中多次实例化它,或者使用args
执行其他操作。
fun main(args: Array<String>) {
val arr: IntArray = intArrayOf(1,2,3,4)
val charA: CharArray = charArrayOf('a','b','c','d')
printMe(arr, IntArray::iterator)
printMe(charA, CharArray::iterator)
}
fun <T> printMe(args: T, iterator: T.() -> Iterator<*>) {
for (item in args.iterator()) {
println(item)
}
}