How to push a new objects in vec! array?

Here's is the code with a bunch of Error

use std::io;


struct Person {
    name: String,
    age: u32,
    hobby: String,
}

impl Person {
    fn new(name: &str, age: u32, hobby: &str) -> Self {
        Self {
            name: name.to_string(),
            age,
            hobby: hobby.to_string(),
        }
    }
}

fn main() {
    let mut people = vec![
        Person::new("John", 26, "Music"),
        Person::new("Kyle", 22, "Coding"),
        Person::new("Tommy", 17, "-"),
    ];
    
    add_person(&mut people);
    
    println!("The people list:");
    for (i, person) in &people.iter().enumerate() {
      println!("index: {}, name: {}, age: {}, hobby: {}", i, person.name, person.age, person.hobby);
    }
}

fn add_person(people: &mut vec!) {
    println!("Add a new person in people list");
    
    // person name
    println!("Person name >>");
    let mut person_name: String = String::new();
    io::stdin()
      .read_line(&mut person_name)
      .expect("Something went wrong");
    let name: &str = person_name.trim();
 
    // person age
    let mut age: u32 = 0;
    loop {
      println!("Person age >>")
      let mut person_age: String = String::new();
      io::stdin()
        .read_line(&mut person_age)
        .expect("Something went wrong");
      let person_age: u32 = match person_age.trim().parse() {
         Ok(num) => num,
         Err(_) => {
           continue println!("It's not valid age!");
         },
      };
      
      break age = person_age;
    };
   
    // person hobby
    println!("Person hobby >>")
    let mut person_hobby: String = String::new();
    io::stdin()
      .read_line(&mut person_hobby)
      .expect("Something went wrong");
    let hobby: &str = person_hobby.trim();
    
    people.push(Person::new(name, age, hobby))
}

First and foremost, we have the syntax error here:

The error itself:

error: expected one of `(`, `[`, or `{`, found `)`
  --> src/main.rs:35:32
   |
35 | fn add_person(people: &mut vec!) {
   |                                ^ expected one of `(`, `[`, or `{`

The reason is that vec! is not a type (and cannot be a type, syntactically). To get the type based on value, we can ask the compiler by triggering an error consciously (we have to comment out the add_person function - since it has a syntax error, the whole code can't be type-checked while it is present):

let mut people: () = vec![
    Person::new("John", 26, "Music"),
    Person::new("Kyle", 22, "Coding"),
    Person::new("Tommy", 17, "-"),
];

Error:

error[E0308]: mismatched types
  --> src/main.rs:21:22
   |
21 |   let mut people: () = vec![
   |  _________________--___^
   | |                 |
   | |                 expected due to this
22 | |     Person::new("John", 26, "Music"),
23 | |     Person::new("Kyle", 22, "Coding"),
24 | |     Person::new("Tommy", 17, "-"),
25 | | ];
   | |_^ expected `()`, found struct `Vec`
   |
   = note: expected unit type `()`
                 found struct `Vec<Person>`

So the type is Vec<Person>. Putting the add_person back and replacing the vec! with the type, we get another bunch of syntax errors; two of them are resolved by simply following the help: add ';' here messages, and the third - by understanding that continue operator cannot receive arguments, so println must be moved before it.

Finally, this error:

error[E0277]: `&Enumerate<std::slice::Iter<'_, Person>>` is not an iterator
  --> src/main.rs:30:24
   |
30 |     for (i, person) in &people.iter().enumerate() {
   |                        -^^^^^^^^^^^^^^^^^^^^^^^^^
   |                        |
   |                        `&Enumerate<std::slice::Iter<'_, Person>>` is not an iterator
   |                        help: consider removing the leading `&`-reference
   |

...is, again, resolved by literally following the help message. After that, the code compiles.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.