Stream 和 List 一样,是一种递归的数据结构
从大学到工作一直是java,c++,c,c#这些都不是函数式的编程语言,并且递归已经被判了死刑(通常因为系统方法调用栈太小,且JVM不会做尾递归优化)。所以,Stream这样递归的数据结构,理解起来不是那么自然。
看个简单例子
lazy val fib: Stream[BigInt] = Stream.cons(1, Stream.cons(1, (fib zip fib.tail).map(p => p._1 + p._2)))
非波那且数列,,,好吧,这个例子一点也不简单,对于我来说。
它定义了一个无限的数列。 这在我以前看来简直是不可能的。
一个无限的数列可以进行 (fib zip fib.tail).map(p => p._1 + p._2) 这种疯狂的操作,这怎么可能呢?居然不会堆栈溢出
cons看起来像函数,其实是一个对象
我将其翻译递归表达式
lazy val fib1: Int => List[Int] = { x =>
x match {
case 1 => 1 :: Nil
case 2 => 1 :: 1 :: Nil
case n if n > 2 => 1 :: 1 :: (fib1(n - 1).tail zip fib1(n - 2)).map(p => p._1 + p._2)
}
}
两者性能,不可同日而语
fib因为是一个lazy的Stream,所以在定义不会进行任何计算。只有在调用fib.take(10)时才会计算。依次构造出(1,(1,(2,(3,(5.......这样的递归的数据结构‘
具体可以看这里 http://stackoverflow.com/questions/7225310/scala-pattern-matching-variable 这个问题的一个答案,我画了插图解释