序列和懒惰序列 - 有什么区别和用途?

时间:2014-09-22 20:48:02

标签: swift

我很难理解为什么Swift中有两种不同的结构几乎相同。

  • SequenceOf是不是懒惰?
  • 每种用途的用途是什么?

编辑:我想我还是不明白什么"懒惰"按顺序意味着...... F.e。使用这个使用SequenceOf的代码,该代码据说不是懒惰的:

    func myMap<S: SequenceType, V>(source: S, 
      selector: S.Generator.Element -> V) -> SequenceOf<V>  {
      let seq = SequenceOf {
         _ -> GeneratorOf<V> in
         var gen = source.generate()
         return GeneratorOf {
           let v = gen.next()
           println(v)
           return v == nil ? nil : selector(v!)
         }
      }
      return seq
    }

让我们用

来调用它
    let a = myMap([1, 2, 3], { $0 * 2 })
    var gen = a.generate()
    let v1 = gen.next()
    let v2 = gen.next()

打印

可选(1)

可选(2)

看起来很懒...

编辑#2:

当在懒惰序列上使用地图时,无论如何似乎都在急切地评估元素:

struct TransientView<S: SequenceType> : SequenceType {

    private let seq: S

    init(_ seq: S) {
        self.seq = seq
    }

    func generate()
        -> GeneratorOf<S.Generator.Element> {
            var g = seq.generate()
            return GeneratorOf {
                println("next")
                return g.next()
            }
    }
}

let seq = lazy(map(TransientView([1, 2, 3]), { $0 * 2 })) 

打印&#34; next&#34; 4次......

编辑#3。以下是我目前对此的看法:说#34; SequenceOf不是懒惰&#34;是错误的。更确切地说,#4; SequenceOf使用非惰性.map,.filter等进行扩展&#34;。完全可以编写适用于任何序列的map,filer等惰性版本,包括SequenceOf。但是,Apple决定采用“懒惰”#34;范例不仅适用于序列的实例,也适用于序列元素 - 因此,如果将序列变量声明为惰性,则使用LazySequence,因此扩展是惰性的。我认为这是错误的方法,懒惰的声明不应该转移到元素 - 相反,元素应该保持懒惰,只要它是可能的。很容易将懒惰转换为渴望,但不可能。

1 个答案:

答案 0 :(得分:12)

  

SequenceOf不是懒惰的吗?

正确。这不是懒惰。这就是懒惰形式存在的原因。

  

每种用途的用途是什么?

Airpseed Velocity可能对各种类型进行了最全面的讨论。 SequenceOf提供了从闭包生成序列的简单方法。它还提供了一种&#34;序列类型转换&#34;将一种序列类型转换为另一种序列类型。

LazySequence主要使用lazy函数创建。 Airspeed Velocity&#39; s Working at being lazy给出了很好的介绍。它的目的是避免在实际需要之前生成元素,这对于无限序列特别有用,但在任何可能不需要所有元素的情况下都很有用,并且它们非常容易生成。

我是否提到你应该阅读Airspeed Velocity如果你想深入了解这些东西?但是仍然值得记住的是,我们只能从标题中推断出我们可以从devforum讨论中获得的内容,以及从我们对Swift知道的内容中得到的内容。较低级别的类型尚未有详细记录,并且不属于任何官方的#34; docs,他们已经多次改变了beta。因此,在未来的版本中,正是 Swift团队对他们的意图并不总是很容易。这是迄今为止我们所知道的最好的。


编辑:正如我在评论中指出的那样,没有map函数在6.1b3中获取并返回LazySequencemap上只有LazySequence方法。但是如果我们想要的话,我们可以建立一个,也许他们最终会添加它:

func map<S: SequenceType, U>(source: LazySequence<S>, transform: S.Generator.Element -> U) -> LazySequence<MapSequenceView<S, U>> {
  return source.map(transform)
}