简体   繁体   中英

What is the difference between literal string and Args in Rust?

I have a string parsing function using regex: fn parse(s: &str) -> Option<MyObj> . It works when testing with parse("test string") . But failed when using Args . The failure is that the regex could not matching anything from s .

The way I used Args is: args().map(|arg| parse(&arg)).collect() . I could not see type error here. And println in parse shows s is the same string as "test string".


Updated my description. I am not sure if my problem is related with how String and str are different. Because I was using str and it still failed.

extern crate regex;

use regex::Regex;
use std::env::args;

struct IPRange {
    start: u32,
    mask: u8,
}

fn parse_iprange(ipr: &str) -> Option<IPRange> {
    let parser = Regex::new(
        r"^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/(\d+|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$",
    )
    .unwrap();
    let caps = parser.captures(ipr).unwrap();
    return Some(IPRange { start: 0, mask: 0 });
}

fn main() {
    let v: Vec<_> = args().map(|arg| parse_iprange(&arg)).collect();
}
$ RUST_BACKTRACE=1 cargo run 192.168.3.1/24
    Finished dev [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/ip_helper 192.168.3.1/24`
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:345:21
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:215
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:385
   6: rust_begin_unwind
             at src/libstd/panicking.rs:312
   7: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
   8: core::panicking::panic
             at src/libcore/panicking.rs:49
   9: <core::option::Option<T>>::unwrap
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libcore/macros.rs:10
  10: ip_helper::parse_iprange
             at src/main.rs:18

The first item of args() is implementation behavior:

The first element is traditionally the path of the executable, but it can be set to arbitrary text, and may not even exist. This means this property should not be relied upon for security purposes.

So, you should skip it in your case:

let v: Vec<_> = args().skip(1).map(|arg| parse_iprange(&arg)).collect();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM