使用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 }) 

ByteDouble FloatFloatIntLong整数或Short整数优先于%运算符,但forEach是返回类型为Unit的函数。

在第二种方法中,您在isPrime(Int)有正确的表达式。 以下是对您的一些建议:

  1. listNumber1to100在你的代码中不包括100,如果你想在listNumber1to100到100中包含100,你传递的lambda应该像这样改变:

     val listNumber1to100 = listNumbers.takeWhile { it <= 100 } 
  2. listNumber1to100.asSequence()在这里是多余的,因为listNumber1too100本身就是一个实现SequenceTakeWhileSequence

  3. 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()) 

我发现这个解决方案,工作但是为什么我可以有一个非数字在这里提醒的右侧