Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust如何找出迭代器的上限?_Rust - Fatal编程技术网

Rust如何找出迭代器的上限?

Rust如何找出迭代器的上限?,rust,Rust,我正在浏览几个生锈的例子,其中有一段特殊的代码,我并不真正理解它是如何工作的。特别是高阶函数。我的重点是这段代码: let sum_of_squared_odd_numbers: u32 = (0..).map(|n| n * n) // All natural numbers squared .take_while(|&n| n < upper) // Below upper limit .filter(|n|

我正在浏览几个生锈的例子,其中有一段特殊的代码,我并不真正理解它是如何工作的。特别是高阶函数。我的重点是这段代码:

let sum_of_squared_odd_numbers: u32 =
    (0..).map(|n| n * n)             // All natural numbers squared
         .take_while(|&n| n < upper) // Below upper limit
         .filter(|n| is_odd(*n))     // That are odd
         .fold(0, |sum, i| sum + i); // Sum them
设奇数的平方和:u32=
(0...map(|n | n*n)//所有自然数的平方
.当(|&n | n<上限)//低于上限时
.filter(|n |为_奇数(*n))//为奇数的
.fold(0,| sum,i | sum+i);//求和
以下是我的问题:

  • 编译器如何知道
    (0..)
    何时结束?循环是否在编译时展开,是否对所有lambda进行了计算

  • 与命令式版本相比,这种内存不是非常低效吗?例如,
    (0..).map(|n | n*n)
    本身将占用O(n)内存


  • 我不是铁锈专家,但是评论

    // All natural numbers squared
    
    告诉我,列表(或流、枚举等)无法完全计算。所以我会把赌注押在某种懒惰的评估上

    在这种情况下,范围将携带一个内部状态,每次使用时都会计算下一个元素。然后,通过“存储”相应的实现(而不是直接对其进行评估)来实现反变形(折叠、映射)

    更新:我在部分时忽略了
    拍摄。这种方法似乎有责任(也根据评论)实际强制进行评估。之前的一切只计算范围抽象,即没有任何具体元素。这是可能的,因为函数可以被组合


    这种行为的标准例子是

    我不是铁锈专家,而是评论

    // All natural numbers squared
    
    告诉我,列表(或流、枚举等)无法完全计算。所以我会把赌注押在某种懒惰的评估上

    在这种情况下,范围将携带一个内部状态,每次使用时都会计算下一个元素。然后,通过“存储”相应的实现(而不是直接对其进行评估)来实现反变形(折叠、映射)

    更新:我在
    部分时忽略了
    拍摄。这种方法似乎有责任(也根据评论)实际强制进行评估。之前的一切只计算范围抽象,即没有任何具体元素。这是可能的,因为函数可以组合


    这种行为的标准示例是编译程序不知道
    (0..)
    何时结束。但是,迭代器是惰性的(正如您链接到的页面上所提到的),并且
    .take_while(|&n | n
    语句将在
    n
    大于或等于
    upper
    时停止序列,编译器不知道
    (0..)
    何时结束。但是,迭代器是惰性的(正如您链接到的页面上所提到的),只要
    大于或等于
    上限,take_while(|&n | n
    语句就会停止序列

    编译器如何知道
    (0..)
    何时结束

    编译器根本不知道。这是一个范围文字,特别是一个。注意,它实现了trait。
    迭代器的核心部分是:

    无论何时在最终适配器上调用
    next
    ,适配器堆栈的每一层都做了足够的工作来获得下一个值。在原始示例中,
    fold
    是一个迭代器终止符,它使用整个迭代器,调用
    next
    ,直到没有更多值为止

    正如您所说,您并不想尝试超过某个范围的最大值,这取决于它是在调试模式还是发布模式下构建的

    编译器如何知道
    (0..)
    何时结束

    编译器根本不知道。这是一个范围文字,特别是一个。注意,它实现了trait。
    迭代器的核心部分是:

    无论何时在最终适配器上调用
    next
    ,适配器堆栈的每一层都做了足够的工作来获得下一个值。在原始示例中,
    fold
    是一个迭代器终止符,它使用整个迭代器,调用
    next
    ,直到没有更多值为止


    作为一个例子,您并不想尝试超过某个范围的最大值,因为它也会超过最大值,这取决于它是在调试模式还是发布模式下构建的。

    您的意思是说
    让foo=(0...map(| n | n*n);让bar=foo.take_while(…);bar
    的编译方式与let bar=(0..).map(|n | n*n)不同。以_while(…)
    为例?Haskell是一个有点奇怪的例子,因为它使用隐式thunks,并且比Rust更“高级”。一个更明显的例子是类似于Ocaml的惰性列表,它只是“A*(unit->”A stream)的
    Nil | Cons
    。主要区别在于Haskell的懒惰是发生在代码上的,而显式的懒惰是从代码中产生的。
    take\u而
    不负责任
    map
    take_,而
    filter
    是接受并返回惰性迭代器的适配器
    fold
    是消费者,它接受迭代器并生成值<代码>take_while
    的作用是,如果谓词失败,它可以结束流。你的意思是说
    让foo=(0...map(| n | n*n);让bar=foo.take_while(…);bar
    的编译方式与let bar=(0..).map(|n | n*n)不同。以_while(…)
    为例?Haskell是一个有点奇怪的例子,因为它使用隐式thunks,并且比Rust更“高级”。一个更明显的例子是类似于Ocaml的惰性列表,它只是“A*(unit->”A stream)的
    Nil | Cons
    。主要的区别在于Haskell的懒惰是发生在代码中的事情,而显式的懒惰则是你所做的事情
    // Note the type is
    // Filter<TakeWhile<Map<RangeFrom<_>, [closure]>, [closure]>, [closure]>
    let () = 
        (0..)
        .map(|n| n * n)            
        .take_while(|&n| n < 20)
        .filter(|n| n % 2 == 0);
    // At this point, we still haven't even looked at a single value