Scala中sliding方法行为异常,为何两段代码结果不同?
解释Scala代码中的执行差异
核心原因很简单:Scala里String.sliding方法返回的是**Iterator[String]迭代器**,而迭代器是单次遍历的对象——一旦你通过调用length、dropWhile这类方法遍历过它,迭代器就会被耗尽,后续再访问就没有元素了。
代码示例1分析
val s = "abcdefg" val slides = s.sliding(4) val n1 = slides.length val n2 = slides.dropWhile(foo).length println(n1) // 4 println(n2) // 0 println(slides.length) // 0
- 这里把
sliding(4)的结果赋值给了变量slides,全程复用的是同一个迭代器实例。 - 第一次调用
slides.length:会完整遍历迭代器统计元素数量(得到4),此时迭代器内部的指针已经走到末尾,没有剩余元素了。 - 后续调用
slides.dropWhile(foo).length和slides.length时,迭代器已经被掏空,自然只能返回0。
代码示例2分析
val s = "abcdefg" println(s.sliding(4).length) // 4 println(s.sliding(4).dropWhile(foo).length) // 3 println(s.sliding(4).length) // 4
- 这里每次调用
s.sliding(4)都会创建一个全新的迭代器实例,三个迭代器彼此独立,互不影响。 - 第一次调用:新迭代器遍历后得到长度4,用完就被丢弃。
- 第二次调用:全新的迭代器执行
dropWhile(foo)(根据描述,foo检查字符串不含"c"),过滤掉前缀中符合条件的元素后,剩余3个元素,所以长度为3。 - 第三次调用:再次创建新迭代器,遍历后依然得到长度4。
额外提示
如果需要重复访问sliding的结果,不要直接复用迭代器,而是把它转换成可重复访问的集合,比如:
val slides = s.sliding(4).toList // 转换成List,可多次遍历
内容的提问来源于stack exchange,提问作者Wojciech Szlosek
相关产品推荐
相关产品推荐

