首页 > 解决方案 > 为什么使用while循环抛出未解决的引用错误,而for循环在kotlin中运行良好

问题描述

刚在使用 kotlin 时遇到问题。检查下面的代码示例。下面的代码执行没有编译错误。但最初我在下面的代码中用 while 代替了 for 循环。那就是向元素抛出未解决的引用错误。

为什么我们在 Kotlin 中会有如此奇怪和意想不到的行为。刚开始使用 kotlin 请原谅。

fun main(args: Array<String>) {
  /* Enter your code here. Read input from STDIN. Print output to STDOUT */
  val myarr=intArrayOf(1,2,3,4)

  for(element in myarr){
      println(element)
  }

下面是我遇到错误的代码。我的问题是为什么它适用于 for 循环而不适用于 while

fun main(args: Array<String>) {
  /* Enter your code here. Read input from STDIN. Print output to STDOUT */
  val myarr=intArrayOf(1,2,3,4)

  while(element in myarr){
      println(element)
  }

}

标签: kotlin

解决方案


while循环需要一个布尔参数。in在这种情况下不是迭代器,它相当于in布尔检查。例子:

fun demo(){
    val x = 2;
    val l = listOf(1, 2, 3);
    while(x in l){

    }
}

请注意,这是可怕的代码,它会导致无限循环。但它确实向您展示了这一点;在 while 循环中,in用于布尔值,而不是范围。这也适用于数组。

它是一个未解析的引用的原因是因为您正在进行布尔检查,而不是 for 循环。For 循环自动声明该字段,其中为 a while,但还if需要现有字段(即val x = something)或直接声明(即while (2 in l))。后者删除变量名。

所以while循环不会像for. 您有五个用于迭代可迭代对象的选项:

  1. for(i in 0 until list.size)-list.size可以是任何调用,只要它是一个 int
  2. for (item in list)- 这要求列表是可迭代的。
  3. var i = 0;
    while(i < list.size) {
        // remember to increment `i`, otherwise it's an infinite loop
    }
    
  4. list.forEach { }list.forEachIndexed { i, item -> TODO() }
  5. 我不推荐这样做,因为使用 Kotlin 标准库有更好的选择,但它仍然是一个选择:list.stream().forEach({ item -> TODO() })

如果您在 while 循环中按住 CTRL+单击 IntelliJ in,您将被重定向到override fun contains(element: @UnsafeVariance E): Boolean. 如您所见,此方法返回一个布尔值。如果您在 for 循环中执行相同操作,您将被重定向到override fun iterator(): Iterator<E>. 如您所见,它们有两种截然不同的返回类型。while循环使用布尔值,循环for将使用迭代器。in在这种情况下只是语法。

最后,我强烈建议您使用 for 循环,特别是因为您有一个数组。不过,while 循环没有任何问题,使用for是个人喜好。


为了结束我所说的,你得到一个未解析的引用的原因是因为 while 循环实际上并没有声明一个变量。如果您添加一个变量,您的代码将编译,但如果项目在数组中,这将是一个无限循环:

fun main(args: Array<String>) {
  val myarr=intArrayOf(1,2,3,4)
  var element = 0; //if this is in the list, the the while loop is an infinite loop.
  while(element in myarr){
      println(element)
  }

}

推荐阅读