Curso de choque de óxido. La regla de tres: parámetros, iteradores y cierres

A continuación se muestra una traducción de una parte de la serie de artículos Rust Crash Course de Michael Snoiman, que se centra en los mecanismos de paso de parámetros, iteradores y cierres con respecto a cómo se transfiere la propiedad y se relaciona con la mutabilidad y la vida útil.



También intenté traducir lo más cerca posible del estilo del autor, pero reduje algunos interdomos y exclamaciones que no son muy significativas para el significado.


Tipos de parámetros



Primero, quiero lidiar con un posible error. Este podría ser uno de esos delirios de "mi cerebro fue dañado por Haskell" que las personas imperativas no enfrentan, así que me disculpo de antemano por mis bromas sobre mí y otros haskellistas.







¿Coinciden las firmas de tipo de las dos funciones?







fn foo(mut person: Person) { unimplemented!() }
fn bar(person: Person ) { unimplemented!() }
      
      





: " !". , (exactly the same). (inner mutability) person



, . person



, . : , foo



:







fn main() {
    let alice = Person { name: String::from("Alice"), age: 30 };
    foo(alice); // !
}
      
      





:







fn baz(person: &Person) { unimplemented!() }
fn bin(person: &mut Person) { unimplemented!() }
      
      





-, , baz



, bin



foo



. Person



, Person



. baz



bin



? ? , foo



bar



, , mut



— . !







:







fn main() {
    let mut alice = Person { name: String::from("Alice"), age: 30 };
    baz(&alice); // 
    bin(&alice); // !
    bin(&mut alice); //   
}
      
      





bin



, bin



, . . , : , , ( 2).







, :







  • ( ) foo



  • , baz



  • , bin





, , , , , . (. , , ; foo



, baz



bin



person



).







vs.



. , ? ! birthday



, - 1.







#[derive(Debug)]
struct Person {
    name: String,
    age: u32,
}

fn birthday_immutable(person: Person) -> Person {
    Person {
        name: person.name,
        age: person.age + 1,
    }
}

fn birthday_mutable(mut person: Person) -> Person {
    person.age += 1;
    person
}

fn main() {
    let alice1 = Person { name: String::from("Alice"), age: 30 };
    println!("Alice 1: {:?}", alice1);
    let alice2 = birthday_immutable(alice1);
    println!("Alice 2: {:?}", alice2);
    let alice3 = birthday_mutable(alice2);
    println!("Alice 3: {:?}", alice3);
}
      
      





:







  • _immutable



    , Person



    , Person



    . Rust, , .
  • , , .
  • alice1



    alice2



    main



    , (move) .
  • alice2



    — , , .


vs.



, Rust: — (it's unusual). , . , mut



.







, : , ('



) (lifetime parameters), , . , " ". . , Rust Book.







, , , , .







#[derive(Debug)]
struct Person {
    name: String,
    age: u32,
}

fn birthday_immutable(person: &mut Person) {
    person.age += 1;
}

fn birthday_mutable<'a>(mut person: &'a mut Person, replacement: &'a mut Person) {
    person = replacement;
    person.age += 1;
}

fn main() {
    let mut alice = Person { name: String::from("Alice"), age: 30 };
    let mut bob = Person { name: String::from("Bob"), age: 20 };
    println!("Alice 1: {:?}, Bob 1: {:?}", alice, bob);
    birthday_immutable(&mut alice);
    println!("Alice 2: {:?}, Bob 2: {:?}", alice, bob);
    birthday_mutable(&mut alice, &mut bob);
    println!("Alice 3: {:?}, Bob 3: {:?}", alice, bob);
}

// does not compile
fn birthday_immutable_broken<'a>(person: &'a mut Person, replacement: &'a mut Person) {
    person = replacement;
    person.age += 1;
}
      
      





birtday_immutable



. , . , . : , , (: person



. , , ).







birthday_mutable



— , . : person



replacement



. , person



. , — (person = replacement



). , person



, , . , , , , person



:







warning: value passed to `person` is never read
      
      





, main



bob



alice



. ? , . , main



, .







, birthday_immutable_broken



. , . , person



, .







: , , , .







vs.



, , . , , . , , .









:







fn needs_mutable(x: &mut u32) {
    *x *= 2;
}

fn needs_immutable(x: &u32) {
    println!("{}", x);
}

fn main() {
    let mut x: u32 = 5;
    let y: &mut u32 = &mut x;
    needs_immutable(y);
    needs_mutable(y);
    needs_immutable(y);
}
      
      





, , , . y



&mut u32



, needs_immutable



, &u32



. , .







: , , , , ( , ).









:









, . , , . , . , , , . , , .







1



, 10. .







fn double(mut x: u32) {
    x *= 2;
}

fn main() {
    let x = 5;
    double(x);
    println!("{}", x);
}
      
      





: , (asterisk, *



) , (dereference) (. — — , , ).







//     
fn double(x: &mut u32) {
    //  
    //    ,    
    *x *= 2;
}

fn main() {
    //     
    let mut x = 5;
    //     
    double(&mut x);
    println!("{}", x);
}
      
      







?







fn main() {
    let nums = vec![1, 2, 3, 4, 5];
    for i in nums {
        println!("{}", i);
    }
}
      
      





, 1 5. ?







fn main() {
    for i in 1..3 {
        let nums = vec![1, 2, 3, 4, 5];
        for j in nums {
            println!("{},{}", i, j);
        }
    }
}
      
      





1,1



, 1,2



, ..., 2,1



, ..., 2,5



. - . nums



. ?







fn main() {
    let nums = vec![1, 2, 3, 4, 5];
    for i in 1..3 {
        for j in nums {
            println!("{},{}", i, j);
        }
    }
}
      
      





. .







error[E0382]: use of moved value: `nums`
 --> main.rs:4:18
  |
4 |         for j in nums {
  |                  ^^^^ value moved here in previous iteration of loop
  |
  = note: move occurs because `nums` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

error: aborting due to previous error
      
      





. , , (move) nums



. , , nums



. .







, nums



for



. , . . , nums



. ()!







nums



, (borrowing)? , !







fn main() {
    let nums = vec![1, 2, 3, 4, 5];
    for i in 1..3 {
        for j in &nums {
            println!("{},{}", i, j);
        }
    }
}
      
      





, : j



? . println!



, :







let _: u32 = j;
      
      





error[E0308]: mismatched types
 --> src/main.rs:5:26
  |
5 |             let _: u32 = j;
  |                    ---   ^
  |                    |     |
  |                    |     expected `u32`, found `&{integer}`
  |                    |     help: consider dereferencing the borrow: `*j`
  |                    expected due to this
      
      





, :







let _: &u32 = j;
      
      





nums



, , . " " ? !







fn main() {
    let nums = vec![1, 2, 3, 4, 5];
    for i in 1..3 {
        for j in &mut nums {
            let _: &mut u32 = j;
            println!("{},{}", i, j);
            *j *= 2;
        }
    }
}
      
      





. . . , , .







fn main() {
    // nums   
    let mut nums = vec![1, 2, 3, 4, 5];
    for i in 1..3 {
        for j in &mut nums {
            let _: &mut u32 = j;
            println!("{},{}", i, j);
            *j *= 2;
        }
    }
}
      
      





, . , , .









vec



, . ,







for j in &mut nums {
```Rust
 
```Rust
for j in nums.iter_mut() {
      
      





:







pub fn iter_mut(&mut self) -> IterMut<T>
      
      





iter()



, :







fn main() {
    let nums = vec![1, 2, 3, 4, 5];
    for i in 1..3 {
        for j in nums.iter() {
            let _: &u32 = j;
            println!("{}, {}", i, j);
        }
    }
}
      
      





? into_iter()



. , (into) , ( , nums



Vec



). . , let nums



:







fn main() {
    let nums = vec![1, 2, 3, 4, 5];
    for i in 1..3 {
        for j in nums.into_iter() {
            println!("{}, {}", i, j);
        }
    }
}
      
      





fn main() {
    for i in 1..3 {
        //   nums   into_iter()
        //       
        let nums = vec![1, 2, 3, 4, 5];
        for j in nums.into_iter() {
            println!("{}, {}", i, j);
        }
    }
}
      
      





for



, . for



, . into_iter()



, IntoIterator



. for x in y



, into_iter()



y



. , Iterator



.







2



, IntoIterator



InfiniteUnit



. Iterator



! , . ( : , ).







struct InfiniteUnit;

fn main() {
    let mut count = 0;
    for _ in InfiniteUnit {
        count += 1;
        println!("count == {}", count);
        if count >= 5 {
            break;
        }
    }
}
      
      





struct InfiniteUnit;

impl IntoIterator for InfiniteUnit {
    type Item = ();
    type IntoIter = InfiniteUnitIter;

    fn into_iter(self) -> Self::IntoIter {
        InfiniteUnitIter
    }
}

struct InfiniteUnitIter;

impl Iterator for InfiniteUnitIter {
    type Item = ();

    fn next(&mut self) -> Option<()> {
        Some(())
    }
}

fn main() {
    let mut count = 0;
    for _ in InfiniteUnit {
        count += 1;
        println!("count == {}", count);
        if count >= 5 {
            break;
        }
    }
}
      
      





, .. repeat



, . .







struct InfiniteUnit;

impl IntoIterator for InfiniteUnit {
    type Item = ();
    type IntoIter = std::iter::Repeat<()>;

    fn into_iter(self) -> Self::IntoIter {
        std::iter::repeat(())
    }
}

fn main() {
    let mut count = 0;
    for _ in InfiniteUnit {
        count += 1;
        println!("count == {}", count);
        if count >= 5 {
            break;
        }
    }
}
      
      







, (flavors), :







  • into_iter



    — ,
  • iter



  • iter_mut()





iter_mut()



, .









, . , (local scope). .







: , , , . , , , . , . , , , JS.







. , ?







fn main() {
    fn say_hi() {
        let msg: &str = "Hi!";
        println!("{}", msg);
    };

    say_hi();
    say_hi();
}
      
      





. :







fn main() {
    let msg: &str = "Hi!";
    fn say_hi() {
        println!("{}", msg);
    };
    say_hi();
    say_hi();
}
      
      





, :







error[E0434]: can't capture dynamic environment in a fn item
 --> main.rs:4:24
  |
4 |         println!("{}", msg);
  |                        ^^^
  |
  = help: use the `|| { ... }` closure form instead

error: aborting due to previous error
      
      





, : . :







fn main() {
    let msg: &str = "Hi!";
    let say_hi = || {
        println!("{}", msg);
    };
    say_hi();
    say_hi();
}
      
      





( ||



), . .







: let say_hi = || println!("{}", msg);



, .







3



, say_hi



: msg



. fn



.







:







fn main() {
    let msg: &str = "Hi!";
    let say_hi = |msg| println!("{}", msg);
    say_hi(msg);
    say_hi(msg);
}
      
      





:







fn main() {
    let msg: &str = "Hi!";
    fn say_hi(msg: &str) {
        println!("{}", msg);
    }
    say_hi(msg);
    say_hi(msg);
}
      
      





, say_hi



.









say_hi



? , : , . , , u32



, :







fn main() {
    let msg: &str = "Hi!";
    let say_hi: u32 = |msg| println!("{}", msg);
}
      
      





:







error[E0308]: mismatched types
 --> src/main.rs:3:23
  |
3 |     let say_hi: u32 = |msg| println!("{}", msg);
  |                 ---   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found closure
  |                 |
  |                 expected due to this
  |
  = note: expected type `u32`
          found closure `[closure@src/main.rs:3:23: 3:48]`
      
      





[closure@main.rs:3:23: 3:48]



… , :







fn main() {
    let msg: &str = "Hi!";
    let say_hi: [closure@main.rs:3:23: 3:48] = |msg| println!("{}", msg);
}
      
      





:







error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `@`
 --> src/main.rs:3:25
  |
3 |     let say_hi: [closure@main.rs:3:23: 3:48] = |msg| println!("{}", msg);
  |         ------          ^ expected one of 7 possible tokens
  |         |
  |         while parsing the type for `say_hi`
      
      





. ?









. . . , ? , :







fn main() {
    let say_message = |msg: &str| println!("{}", msg);
    call_with_hi(say_message);
    call_with_hi(say_message);
}

fn call_with_hi<F>(f: F) {
    f("Hi!");
}
      
      





msg



. , -, , . . , .







F



, . F



, . , :







error[E0618]: expected function, found `F`
 --> src/main.rs:8:5
  |
7 | fn call_with_hi<F>(f: F) {
  |                    - `F` defined here
8 |     f("Hi!");
  |     ^-------
  |     |
  |     call expression requires function
      
      





: , F



. - , : Fn



!







fn call_with_hi<F>(f: F)
    where F: Fn(&str) -> ()
{
    f("Hi!");
}
      
      





F



, , &str



, . , -, .







fn call_with_hi<F>(f: F)
    where F: Fn(&str)
{
    f("Hi!");
}
      
      





, Fn



, .







4



say_message



main



, .







fn main() {
    call_with_hi(say_message);
    call_with_hi(say_message);
}

fn say_message(msg: &str) {
    println!("{}", msg);
}

fn call_with_hi<F>(f: F)
    where F: Fn(&str)
{
    f("Hi!");
}
      
      





say_message



, . .







fn main() {
    let name = String::from("Alice");
    let say_something = |msg: &str| println!("{}, {}", msg, name);
    call_with_hi(say_something);
    call_with_hi(say_something);
    call_with_bye(say_something);
    call_with_bye(say_something);
}

fn call_with_hi<F>(f: F)
    where F: Fn(&str)
{
    f("Hi");
}

fn call_with_bye<F>(f: F)
    where F: Fn(&str)
{
    f("Bye");
}
      
      







-? !







fn main() {
    let mut count = 0;

    for _ in 1..6 {
        count += 1;
        println!("You are visitor #{}", count);
    }
}
      
      





, ! .







fn main() {
    let mut count = 0;
    let visit = || {
        count += 1;
        println!("You are visitor #{}", count);
    };

    for _ in 1..6 {
        visit();
    }
}
      
      





:







error[E0596]: cannot borrow `visit` as mutable, as it is not declared as mutable
 --> src/main.rs:9:9
  |
3 |     let visit = || {
  |         ----- help: consider changing this to be mutable: `mut visit`
...
9 |         visit();
  |         ^^^^^ cannot borrow as mutable
      
      





… ? , . , . - . ?







: visit



(captured) count



. , visit



count



. . ? ? , , :







fn main() {
    let mut count = 0;
    let visit = || {
        count += 1;
        println!("You are visitor #{}", count);
    };

    call_five_times(visit);
}

fn call_five_times<F>(f: F)
    where F: Fn()
{
    for _ in 1..6 {
        f();
    }
}
      
      





:







error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
      
      





! : , (Fn



), , (FnMut



). Fn



FnMut



where



. :







error[E0596]: cannot borrow immutable argument `f` as mutable
  --> main.rs:16:9
   |
11 | fn call_five_times<F>(f: F)
   |                       - help: make this binding mutable: `mut f`
...
16 |         f();
   |         ^ cannot borrow mutably
      
      





, . mut



f: F



.







?



Fn



FnMut



?







|| println!("Hello World!");
      
      





- , , Fn



. , call_five_times



, FnMut



, ? — ! , :







call_five_times(|| println!("Hello World!"));
      
      





, Fn



FnMut



. , : , , , . , (FnMut



) , (Fn



) .







(subtyping)? , .







?



, " ", . , , . , , . — (value/move semantics).







, (moves) . String



(Copy



able) u32



. , . , .







fn main() {
    let name = String::from("Alice");

    let welcome = || {
        let name = name; //   
        println!("Welcome, {}", name);
    };

    welcome();
}
      
      





name



welcome



. let name = name;



. , name



? :







fn main() {
    let name1 = String::from("Alice");

    let welcom = || {
        let mut name2 = name1;
        name2 += " and Bob";
        println!("Welcome, {}", name2);
    };

    welcome();
}
      
      





name1



. name2



, , . — , . ? name1



, welcome()



.









. call_five_times



? welcome



:







fn main() {
    let name = String::from("Alice");

    let welcome = || {
        let mut name = name;
        name += " and Bob";
        println!("Welcome, {}", name);
    };

    call_five_times(welcome);
}

fn call_five_times<F>(f: F)
where
    F: Fn(),
{
    for _ in 1..6 {
        f();
    }
}
      
      





, FnOnce



:







error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
  --> main.rs:4:19
   |
4  |     let welcome = || {
   |                   ^^ this closure implements `FnOnce`, not `Fn`
5  |         let mut name = name;
   |                        ---- closure is `FnOnce` because it moves the variable `name` out of its environment
...
10 |     call_five_times(welcome);
   |     --------------- the requirement to implement `Fn` derives from here
      
      





Fn()



FnOnce()



, ? !







error[E0382]: use of moved value: `f`
  --> main.rs:18:9
   |
18 |         f();
   |         ^ value moved here in previous iteration of loop
   |
   = note: move occurs because `f` has type `F`, which does not implement the `Copy` trait
      
      





f



. , f



, . , . FnOnce



.







, :







fn main() {
    let name = String::from("Alice");

    let welcome = || {
        let mut name = name;
        name += " and Bob";
        println!("Welcome, {}", name);
    };

    call_once(welcome);
}

fn call_once<F>(f: F)
where
    F: FnOnce()
{
    f();
}
      
      





.









, Fn



FnMut



, , , . , Fn



FnOnce



FnOnce



, , , , .







move





, , , ( ). "Rust by Example" . , .







, . , , . , . , , . , :







fn pass_by_value(_x: String) {}
fn pass_by_ref(_x: &String) {}

fn pass_by_mut_ref(x: &mut String) {
    pass_by_ref(x);     //   
    pass_by_value(*x);  //    
}

fn main() {}
      
      





, . , (implicit). , . . , - , , (captured), , , .







, , , , :







  • ,
  • , . , (is dropped), .
  • , - ( , ).


, :







, — .

, , . : , . :







fn main() {
    // owned by main
    let name_outer = String::from("Alice");

    let say_hi || {
        // force a move, again, we'll get smarter in a second
        let name_inner = name_outer;
        println!("Hello, {}", name_inner);
    };

    // main no longer owns name_outer, try this:
    println!("Using name from main: {}", name_outer); // error!

    // but name_inner lives on, in say_hi!
    say_hi(); // success
}
      
      





, () — name_outer



, .







, . let name_inner = name_outer;



. name_outer



. , , name_outer



. ( say_hi()



). , . . , , name_outer



:







fn main() {
    // owned by main
    let name_outer = String::from("Alice");

    let say_hi || {
        // use by ref
        let name_inner = &name_outer;
        println!("Hello, {}", name_inner);
    };

    // main still owns name_outer, this is fine
    println!("Using name from main: {}", name_outer); // success

    // but name_inner lives on, in say_hi!
    say_hi(); // success
    say_hi(); // success
}
      
      





, , name_outer



say_hi



, !







fn main() {
    let say_hi = { //     
        //
        let name_outer = String::from("Alice");

        //  ,     
        || {
            // use by ref
            let name_inner = &name_outer;
            println!("Hello, {}", name_inner);
        }
    };

    //  ,   name_outer      
    // println!("Using name from main: {}", name_outer); // error!

    say_hi();
    say_hi();
}
      
      





, - : " , , , ( — .)". , . , move



:







fn main() {
    let say_hi = {
        let name_outer = String::from("Alice");

        move || {
            let name_inner = &name_outer;
            println!("Hello, {}", name_inner);
        }
    }

    say_hi();
    say_hi();
}
      
      





name_outer



. - , , .







. move



, , . , :







fn main() {
    let name = String::from("Alice");
    let _ = move || { println!("Hello, {}", name) };

    println!("Using name from main: {}", name); // error!
}

      
      





Rust



, . . , , , ? , : . Rust by Example:







, , .







let name_inner = name_outer;



. , , ( ), . .







  • , .
  • , , .
  • , , .


, . , . , , , , .







, , move



, .







, , , move



. , , : " , " .







: ,



:







  • , .
  • , , , , .
  • , , . , , .
  • , move



    .
  • :

    • - , FnOnce



      .
    • , - , FnMut



      , FnOnce



      .
    • Fn



      , FnMut



      FnOnce



      .


, , , , , . Rust by example.







, :







fn call_fn<F>(f: F) where F: Fn() {
    f()
}

fn call_fn_mut<F>(mut f: F) where F: FnMut() {
    f()
}

fn call_fn_once<F>(f: F) where F: FnOnce() {
    f()
}
      
      







main



:







fn main() {
    let name = String::from("Alice");
    let say_hi = || println!("Hello, {}", name);
    call_fn(say_hi);
    call_fn_mut(say_hi);
    call_fn_once(say_hi);
}
      
      





name



, say_hi



, , , , name



. , say_hi



Fn



, FnMut



FnOnce



, .







// bad!
fn main() {
    let say_hi = {
        let name = String::from("Alice");
        || println!("Hello, {}", name)
    };
}
      
      





, . name



. , , , . , , :







fn main() {
    let say_hi = {
        let name = String::from("Alice");
        || {
            let name = name;
            println!("Hello, {}", name)
        }
    };

    // call_fn(say_hi);
    // call_fn_mut(say_hi);
    call_fn_once(say_hi);
}
      
      





FnOnce



, , . ! name



, ( - — ):







fn main() {
    let say_hi = {
        let name = String::from("Alice");
        move || println!("Hello, {}", name)
    };

    call_fn(&say_hi);
    call_fn_mut(&say_hi);
    call_fn_once(&say_hi);
}
      
      





, Fn



, FnMut



FnOnce



. , say_hi



, call_fn



. ( ), , , . ( — .) , .







fn main() {
    let say_hi = {
        let name = String::from("Alice");
        || std::mem::drop(name)
    };
    //call_fn(say_hi);
    //call_fn_mut(say_hi);
    call_fn_once(say_hi);
}
      
      





drop



name



. , , , . , move



, .







fn main() {
    let mut say_hi = {
        let mut name = String::from("Alice");
        move || {
            name += " and Bob";
            println!("Hello, {}", name);
        }
    };
    //call_fn(say_hi);
    call_fn_mut(&mut say_hi);
    call_fn_once(&mut say_hi);
}
      
      





+=



String



, . . , name



. name



, (move



) . say_hi



, mut



.







say_hi



, &mut



, (1) , , (2) . call_fn



, FnMut



FnOnce



, Fn



.







? " and Bob"



name



?







fn main() {
    let mut name = String::from("Alice");
    let mut say_hi = || {
        name += " and Bob";
        println!("Hello, {}", name);
    };
    //call_fn(say_hi);
    call_fn_mut(&mut say_hi);
    call_fn_once(&mut say_hi);
}
      
      





name



, .







// bad!
fn main() {
    let mut name = String::from("Alice");
    let mut say_hi = || {
        name += " and Bob";
        println!("Hello, {}", name);
    };
    //call_fn(say_hi);
    call_fn_mut(&mut say_hi);
    call_fn_once(&mut say_hi);

    println!("And now name is: {}", name);
}
      
      





say_hi



, println!



, name



, . - (lexical lifetimes). ( ) " " (non-lexical lifetimes), #![feature(nll)]



. , :







fn main() {
    let mut name = String::from("Alice");
    {
        let mut say_hi = || {
            name += " and Bob";
            println!("Hello, {}", name);
        };
        //call_fn(say_hi);
        call_fn_mut(&mut say_hi);
        call_fn_once(&mut say_hi);
    }

    println!("And now name is: {}", name);
}
      
      





( , ) ( — .):







fn main() {
    let mut name = String::from("Alice");
    let mut say_hi = || {
        println!("Hello, {}", name); // use by ref
        name += " and Bob"; // use by mut ref
        std::mem::drop(name); // use by value
    };

    //call_fn(say_hi);
    //call_fn_mut(say_hi);
    call_fn_oce(say_hi);
}
      
      





, , . , , , .







?



, . - . Rust Book:







, Fn



-, Fn



, , , , , FnMut



FnOnce



.

, " , ". , — FnOnce



. , .







, Rust by Example.









, Fn



. , Fn



FnMut



, FnMut



FnOnce



.







  • FnOnce



  • FnMut



  • Fn





, , , . , Fn



.







5



Ahora que hemos agregado todo lo que hemos aprendido sobre iteradores y cierres, cambie la línea 5 (que comienza con for i in



) para que el programa imprima los números 2,4,6,...,20



dos veces.







fn main() {
    let nums: Vec<u32> = (1..11).collect();

    for _ in 1..3 {
        for i in nums.map(todo!()) {
            println!("{}", i);
        }
    }
}
      
      





Decisión

:







error[E0599]: no method named `map` found for type `std::vec::Vec<u32>` in the current scope
 --> main.rs:5:23
  |
5 |         for i in nums.map(todo!()) {
  |                       ^^^
  |
  = note: the method `map` exists but the following trait bounds were not satisfied:
          `&mut std::vec::Vec<u32> : std::iter::Iterator`
          `&mut [u32] : std::iter::Iterator`
      
      





, nums



. : into_iter()



, iter()



iter_mut()



. , , iter()



. nums.map



nums.iter().map



, todo!()



.







, . : |x| x * 2



. : FnOnce



, FnMut



Fn



?








All Articles