代码之家  ›  专栏  ›  技术社区  ›  RAGHHURAAMM

为什么scala“string”对象的迭代器和“list[int]”对象的迭代器在这里的行为不同?

  •  2
  • RAGHHURAAMM  · 技术社区  · 8 年前

    我只想探索 String 对象和 List[Int] repl中的对象和测试如下所示:

    scala> val list = List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
    list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
    
    scala> val itL = list.iterator
    itL: Iterator[Int] = non-empty iterator
    
    scala> List(8,5,list.size-13).map(itL.take(_).mkString)
    res85: List[String] = List(12345678, 910111213, 141516)
    
    scala> val st = "abcdefghijklmnop"
    st: String = abcdefghijklmnop
    
    scala> val itS = st.iterator
    itS: Iterator[Char] = non-empty iterator
    
    scala> List(8,5,st.size-13).map(itS.take(_).mkString)
    res84: List[String] = List(abcdefgh, abcde, abc)
    

    为什么迭代器的行为不同?我的预期输出 弦 对象的大小写为:

    List[String] = List(abcdefgh, ijklm, nop)
    

    如果可能的话,有人能用例子解释一下吗?

    另一个观察是:迭代器的行为 Range 对象也与 弦 对象 如下图所示:

    scala> val x = (1 to 16)
    x: scala.collection.immutable.Range.Inclusive = Range 1 to 16
    
    scala> val t = (1 to 16).iterator
    t: Iterator[Int] = non-empty iterator
    
    scala> List(8,5,x.size-13).map(t.take(_).mkString)
    res103: List[String] = List(12345678, 12345, 123)
    

    如果 范围 已转换为 List 或 Set 各个迭代器的行为完全符合我的期望:

    scala> val x1 = (1 to 16).toList
    x1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
    
    scala> val t1 = x1.iterator
    t1: Iterator[Int] = non-empty iterator
    
    scala> List(8,5,x1.size-13).map(t1.take(_).mkString)
    res104: List[String] = List(12345678, 910111213, 141516)
    
    scala> val x2 = (1 to 16).toSet
    x2: scala.collection.immutable.Set[Int] = Set(5, 10, 14, 1, 6, 9, 13, 2, 12, 7, 3, 16, 11, 8, 4, 15)
    
    scala> val t2 = x2.iterator
    t2: Iterator[Int] = non-empty iterator
    
    scala> List(8,5,x2.size-13).map(t2.take(_).mkString)
    res105: List[String] = List(51014169132, 12731611, 8415)
    
    1 回复  |  直到 8 年前
        1
  •  8
  •   jwvh    8 年前

    有一张便条附在 Iterator.take(n:Int) API documentation :

    重用:调用此方法后,应该放弃对其调用的迭代器,只使用返回的迭代器。使用旧的迭代器是未定义的,可能会发生更改,也可能导致对新迭代器的更改。

    看起来你发现了一些“未定义”的行为。