使用kotlin中的高阶函数打印素数时出错
val listNumbers = generateSequence(1) { it + 1 } val listNumber1to100 = listNumbers.takeWhile { it < 100 } val secNum:Unit = listNumber1to100.forEach {it} println(listNumber1to100.asSequence().filter { it%(listNumber1to100.forEach { it })!=0 }.toList())
我在提醒标志中有错误! 这是错误:下面的函数都不能用提供的参数调用
在你的第一种方法中,错误出现在这一行:
it%(listNumber1to100.forEach { it })
Byte
, Double
Float
, Float
, Int
, Long
整数或Short
整数优先于%
运算符,但forEach是返回类型为Unit
的函数。
在第二种方法中,您在isPrime(Int)
有正确的表达式。 以下是对您的一些建议:
-
listNumber1to100
在你的代码中不包括100,如果你想在listNumber1to100
到100中包含100,你传递的lambda应该像这样改变:val listNumber1to100 = listNumbers.takeWhile { it <= 100 }
-
listNumber1to100.asSequence()
在这里是多余的,因为listNumber1too100
本身就是一个实现Sequence
的TakeWhileSequence
。 -
isPrime(Int)
有点令人困惑,因为它检查isComposite,并且它不适用于每个输入(它仅适用于1到99)。 我将用这种方式重写它:fun isPrime(num: Int): Boolean = if (num <= 1) false else !(2..num/2).any { num % it == 0 }
由于素数必须是正数,1是特殊情况(既不是素数也不是合数),如果输入小于或等于1,则返回false。如果不是,则检查输入是否可以被数字范围整除从2到(输入/ 2)。 范围在(input / 2)之前结束是因为如果对于
num % (num/2) == 0
为真,则对于num % 2 == 0
也是如此,反之亦然。 最后,我添加一个!
因为素数不能被任何这些数字整除。最后,你可以像这样通过
isPrime(Int)
过滤一个列表:println(listNumber1to100.filter(::isPrime).toList())
PS。 这只是供参考,而且必须有比这更好的实施。
为了回答你的问题, it
代表了lambda表达式中唯一的lambda参数。 它总是用于只有一个参数的函数文字 。
错误是因为表达式: listNumber1to100.forEach { it }
– 不是一个数字,而是一个Unit
( ref )。
编译器尝试将模运算符与给定的函数签名进行匹配,例如: mod(Byte)
/ mod(Int)
/ mod(Long)
– 等等
val listNumbers = generateSequence(1) { it + 1 } val listNumber1to100 = listNumbers.takeWhile { it < 100 } fun isPrime(num: Int): Boolean = listNumber1to100.asSequence().any { num%it==0 && it!=num && it!=1 } println(listNumber1to100.asSequence().filter { !isPrime(it)}.toList())
我发现这个解决方案,工作但是为什么我可以有一个非数字在这里提醒的右侧