【问题标题】:Implementing Iterable实现可迭代
【发布时间】:2013-11-02 08:25:35
【问题描述】:

如何实现相当于JavaIterable<T>和C#IEnumerable<T>的Scala?基本上,我希望我的集合是可映射的、可过滤的等。集合类应该扩展哪些特征以及是否有简单的方法(例如 C# 中的 yield returnyield break)来创建枚举器?

【问题讨论】:

    标签: scala iterable


    【解决方案1】:

    实现Iterable 特征。所需要的只是iterator 方法。所有其他方法(mapfilter 等)均免费提供。

    class MyIterable[T](xs: Vector[T]) extends Iterable[T] { 
      override def iterator = xs.iterator 
    }
    
    val a = new MyIterable(Vector(1,2,3))
    a.map(_+1) // res0: Iterable[Int] = List(2, 3, 4)
    a.filter(_%2==1) // res1: Iterable[Int] = List(1, 3)
    

    【讨论】:

    • 该代码的性能负担是什么?意思是:需要O(n)时间吗?
    • @StefanKunze,什么需要 O(n) 时间?当然,比如说,索引查找将是线性的。但这毕竟是可迭代的,不可索引。
    • 初始转换为迭代器?
    • "converting" 到一个迭代器是不变的,因为它不需要转换任何东西。它所要做的就是包装向量并在每次调用 next 时推进一个索引。
    • 这段代码除了覆盖迭代器之外什么都不做。我不明白这有什么用。
    【解决方案2】:

    您可以使用scala.collection.Iterable trait 或其不可变版本,它们非常全面和强大。希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      关于枚举器,Scala中有枚举,但使用密封特征+派生类似乎更灵活,例如:

      sealed trait MyEnum {
        lazy val value = 0
      }
      case object MyEnumA extends MyEnum {
        override lazy val value = 1
      }
      case object MyEnumB extends MyEnum {
        override lazy val value = 2
      }
      
      scala> val a = MyEnumB
      a: MyEnumB.type = MyEnumB
      
      scala> a.value
      res24: Int = 2
      
      scala>  val l = List(MyEnumA,MyEnumB)
      l: List[Product with Serializable with MyEnum] = List(MyEnumA, MyEnumB)
      
      scala> l.map(_.value)
      res29: List[Int] = List(1, 2)
      

      如果您不关心将它们映射到除了它们的字符串表示之外的任何东西,您也可以在没有任何内部结构的情况下使用这些对象:

      sealed trait MyEnum
      case object MyEnumA extends MyEnum
      case object MyEnumB extends MyEnum
      
      scala> val a = MyEnumA
      a: MyEnumA.type = MyEnumA
      
      scala> a.toString
      res21: String = MyEnumA
      
      scala> val l = List(MyEnumA,MyEnumB)
      l: List[Product with Serializable with MyEnum] = List(MyEnumA, MyEnumB)
      
      scala> l.map(_.toString)
      res30: List[String] = List(MyEnumA, MyEnumB)
      

      【讨论】:

        猜你喜欢
        • 2013-06-30
        • 2016-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多