我应该如何在Scala中使用#:::/hash冒号?
在一篇关于创建斐波那契数的Stackoverflow帖子中,我找到了方法我应该如何在Scala中使用#:::/hash冒号?,scala,pattern-matching,scala-collections,Scala,Pattern Matching,Scala Collections,在一篇关于创建斐波那契数的Stackoverflow帖子中,我找到了方法。:()。在ScalaDocs中,我发现了一个条目(请参见此处),该条目将哈希冒号方法描述为一个提取器,允许将流与#::进行模式匹配 我意识到我可以像这样使用斐波那契函数 def fibonacci: Stream[Long] = { def tail(h: Long, n: Long): Stream[Long] = h #:: tail(n, h + n) tail(0, 1) } fibonacci(1
。:
()。在ScalaDocs中,我发现了一个条目(请参见此处),该条目将哈希冒号方法描述为一个提取器,允许将流与#::进行模式匹配
我意识到我可以像这样使用斐波那契函数
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
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(自然数)
将导致打印流(0,?)
,因为头部是严格的,这意味着将始终对其进行评估。尾部将是next(1)
,仅在需要时进行评估
在您的示例中,fibonacci(10)
是fibonacci.apply(10)
的语法糖,它在流
类中定义,并在流中生成具有索引的元素
你也可以用流做很多其他的事情。例如,获取第一个大于100的斐波那契数:fibonacci.dropWhile(方法#::
是为流定义的。它类似于列表的:
方法。列表和流之间的主要区别在于流的元素是惰性计算的
最后一行出现了一些scala魔术。实际上,首先计算fibonacci
表达式,它返回一个Stream
对象。该流的第一个和第二个元素是0和1,如示例第三行所示,流的其余部分通过递归调用定义。然后您正在从流中提取第十个元素,其计算结果为55
在下面的代码中,我展示了对第四个列表元素的类似访问
val list = List(1,2,3,4,5)
println(list(3)) // prints 4
简而言之,把流看作无限列表。你可以在这里找到更多关于流的信息对#2的快速回答是,fibonacci(10)
不是一个带参数的函数调用,它是一个不带参数的函数调用,然后调用带参数“10”返回的任何内容
如果这样写的话,会更容易理解:
scala> val s = fibonacci
s: Stream[Long] = Stream(0, ?)
scala> s(10)
res1: Long = 55
感谢您在标题中添加“哈希冒号”,这样我就可以在谷歌上找到这个:)