this post was submitted on 08 Nov 2024
17 points (90.5% liked)

Rust Programming

8191 readers
22 users here now

founded 5 years ago
MODERATORS
 
fn get_links(link_nodes: Select) -> Option<String> {

        let mut rel_permalink: Option<String> = for node in link_nodes {
            link = String::from(node.value().attr("href")?);

            return Some(link);
        };

        Some(rel_permalink)
    }

This is what I'm trying to do, and I've been stuck with this code for an hour, I simply don't know how to put this function togheter.. Essentially I would like to take some link_nodes and just return the link String, but I'm stuck in the use of Option with the ? operator.. Pheraps trying to write it with match would clear things out(?)

Also I come from JavaScript in which expressions do not have their own scope, meaning I'm having troubles to understand how to get out a variable from a for loop, should I initialize the rel_permalink variable as the for loop result?

This are the errors i get:

error[E0308]: mismatched types
  --> src/main.rs:55:49
   |
55 |           let mut rel_permalink: Option<String> = for node in link_nodes {
   |  _________________________________________________^
56 | |             link = String::from(node.value().attr("href")?);
57 | |
58 | |             return Some(link);
59 | |         };
   | |_________^ expected `Option<String>`, found `()`
   |
   = note:   expected enum `Option<String>`
           found unit type `()`
note: the function expects a value to always be returned, but loops might run zero times
  --> src/main.rs:55:49
   |
55 |         let mut rel_permalink: Option<String> = for node in link_nodes {
   |                                                 ^^^^^^^^^^^^^^^^^^^^^^ this might have zero elements to iterate on
56 |             link = String::from(node.value().attr("href")?);
   |                                                          - if the loop doesn't execute, this value would never get returned
57 |
58 |             return Some(link);
   |             ----------------- if the loop doesn't execute, this value would never get returned
   = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 13 points 2 weeks ago

Your return will return from the function, not from the for loop as you probably assume. The for loop itself does not return a value. Only loop based loops can use break to return values, other loops do not.

You also forgot the let keyword in your assignment

I assume you want to return the value of the href attribute for the first node that has one? In that case you want something like

fn get_first_href_value(link_nodes: Select) -> Option<String> {
        for node in link_nodes {
            if let Some(href_value) = node.value().attr("href") {
                return Some(href_value.into());
            }
        }

        None
}

or, more idiomatically

fn get_first_href_value(link_nodes: Select) -> Option<String> {
    link_nodes.into_iter().find_map(|node| node.value().attr("href")).map(|v| v.to_string())
}