【问题标题】:How should I use #:: / hash colon colon in Scala?我应该如何在 Scala 中使用 #:: / hash 冒号冒号?
【发布时间】:2014-01-31 08:00:16
【问题描述】:

在有关创建斐波那契数的 Stackoverflow 帖子中,我找到了方法 #:: (What is the fastest way to write Fibonacci function in Scala?)。在 ScalaDocs 中,我发现了这个条目(参见此处,1)将哈希冒号冒号方法描述为 一个允许使用 #:: 模式匹配流的提取器。

我意识到我可以像这样使用斐波那契函数

def fibonacci: Stream[Long] = {
    def tail(h: Long, n: Long): Stream[Long] = h #:: tail(n, h + n)
    tail(0, 1)
}
fibonacci(10)       //res4: Long = 55
  • 我应该如何理解 ScalaDocs 的解释?你能再举一个例子吗?

  • 为什么不需要在上面的fibonacci函数中定义参数?

【问题讨论】:

  • 感谢您在标题中添加“哈希冒号冒号”,以便我可以从 Google 中找到此内容:)

标签: scala pattern-matching scala-collections


【解决方案1】:

在您的示例中,h #:: tail(n, h + n) 创建了一个新流,其中 h 是流的头部,tail(n, h + n) 是一个将被延迟评估的流。

另一个(也许更简单)的例子是将自然数定义为 BigInt 流。

def naturalNumbers = {
  def next(n: BigInt) : Stream[BigInt] = n #:: next(n + 1)
  next(0)
}

println(naturalNumbers) 将导致打印Stream(0, ?),因为头部是严格的,这意味着它将始终被评估。尾部为next(1),仅在需要时进行评估。

在您的示例中,fibonacci(10)fibonacci.apply(10) 的语法糖,它在 Stream 类中定义,并在流中生成具有索引的元素。

您还可以使用流做很多其他事情。例如获取第一个大于 100 的斐波那契数:fibonacci.dropWhile(_ <= 100).head 或仅打印前 100 个斐波那契数 println(fibonacci.take(100).toList)

【讨论】:

    【解决方案2】:

    #:: 方法是为 Streams 定义的。它类似于列表的:: 方法。 List 和 Stream 的主要区别在于 Stream 的元素是惰性求值的。

    最后一行发生了一些 scala 魔术。实际上,首先您要评估fibonacci 表达式,它会返回一个Stream 对象。此流的第一个和第二个元素是 0 和 1,如下所示示例的第三行,流的其余部分是通过递归调用定义的。然后从流中提取第十个元素,结果为 55。

    在下面的代码中,我展示了对第四个 List 元素的类似访问

    val list = List(1,2,3,4,5)
    println(list(3)) // prints 4
    

    简而言之,将 Streams 视为无限列表。你可以在这里找到更多关于 Streams 的信息http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Stream

    【讨论】:

      【解决方案3】:

      对#2 的快速回答是fibonacci(10) 不是带参数的函数调用,它是不带参数的函数调用,然后调用参数“10”返回的任何内容。

      这样写会更容易理解:

      scala> val s = fibonacci
      s: Stream[Long] = Stream(0, ?)
      
      scala> s(10)
      res1: Long = 55
      

      【讨论】:

        猜你喜欢
        • 2019-09-14
        • 1970-01-01
        • 2011-11-29
        • 1970-01-01
        • 1970-01-01
        • 2012-02-05
        • 2021-10-21
        • 2021-10-26
        • 2015-01-16
        相关资源
        最近更新 更多