"恐慌于断言失败:开始< =结束"使用地图时

时间:2015-02-23 02:19:53

标签: rust

我刚开始接触Rust。

fn main() {
    let s = "aaabbb\naaaccc".to_string();
    let a: Vec<&str> = s.split('\n').map(|s| s.slice_chars(3, s.len())).collect();
    assert_eq!(a, vec!["bbb", "ccc"]);
}

虽然上面的代码有效,但事实并非如此。它在map死亡。

#![feature(process, collections)]
use std::process::Command;

fn main() {
    let output = Command::new("git").args(&["status", "--porcelain"]).output().unwrap_or_else(|e| {
      panic!("failed to execute process: {}", e)
    });
    let s = String::from_utf8_lossy(output.stdout.as_slice()).to_string();
    let a: Vec<&str> = s.split('\n').map(|s| s.slice_chars(3, s.len())).collect();
}

这些是回溯。

$ RUST_BACKTRACE=1 cargo run
     Running `target/hello_world`
thread '<main>' panicked at 'assertion failed: begin <= end', /Users/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-mac/build/src/libcore/str/mod.rs:1478
stack backtrace:
   1:        0x1091266b3 - sys::backtrace::write::hc8e3cee73e646c590nC
   2:        0x10912ba0e - panicking::on_panic::h00b47941f5bc8a02HOL
   3:        0x109110de8 - rt::unwind::begin_unwind_inner::h539538ef7f909326UvL
   4:        0x1091115fe - rt::unwind::begin_unwind_fmt::h7ee8242816be0431quL
   5:        0x10912b29e - rust_begin_unwind
   6:        0x10914a487 - panicking::panic_fmt::hbdb6961ecc952cf7cSv
   7:        0x10914a35a - panicking::panic::h2860b801a6212420fQv
   8:        0x10914bfd1 - str::str.StrExt::slice_chars::hb48fc0a9452c1b98PGD
   9:        0x109110791 - str::StrExt::slice_chars::h13298185343564271120
  10:        0x10910fe14 - main::closure.2239
  11:        0x10910fd13 - iter::Map<I, F>::do_map::h17245677587133977247
  12:        0x10910e7dd - iter::Map<I, F>.Iterator::next::h11146527951811133470
  13:        0x10910dc39 - vec::Vec<T>.FromIterator<T>::from_iter::h11956274897938765189
  14:        0x10910d8bf - iter::IteratorExt::collect::h15101737251385262689
  15:        0x109106f22 - main::h2fa2dff98d35cbb8faa
  16:        0x10912d279 - rust_try_inner
  17:        0x10912d266 - rust_try
  18:        0x10912c1f2 - rt::lang_start::h660a0b4ce4c9ac40HIL
  19:        0x109106f9f - main

感谢您的帮助!

$ rustc --version
rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-20)

3 个答案:

答案 0 :(得分:3)

你超出你的字符串范围。这是一个例子:

fn main() {
    let s = "a";
    let s2 = s.slice_chars(3, s.len());
}

我真的不知道你为什么要做这种切片,所以很难推荐更好的解决方案。

答案 1 :(得分:3)

我想这是因为git的输出没有您期望的格式:可能是因为len()中有一行s.slice_chars(3, s.len())小于3,这对该函数无效。因此,您需要确保正确理解格式,和/或例如将来电置于if,例如if ... { s.slice_chars(3, s.len()) } else { "" }

此外,这里存在域不匹配:slice_chars在代码点上运行,但s.len()返回字符串中的字节数。字节和代码点不一定等价(实际上,当字符串是纯ASCII时,它们仅在UTF-8中等效),因此您应该使用char_len(在任何地方使用代码点),或使用{{1 (到处使用字节)。

答案 2 :(得分:2)

如果程序的输出包含长度小于3个字符的行(例如,仅包含换行符的行),则代码将失败。

您还没有描述您尝试做的事情,但一种可能的解决方案是过滤掉少于3个字符的行:

#![feature(process, collections)]
use std::process::Command;

fn main() {
    let output = Command::new("git").args(&["status", "--porcelain"]).output().unwrap_or_else(|e| {
      panic!("failed to execute process: {}", e)
    });

    let s = String::from_utf8_lossy(output.stdout.as_slice()).to_string();
    let a: Vec<&str> = s.split('\n')
        .filter(|s| s.len() >= 3)
        .map(|s| s.slice_chars(3, s.len()))
        .collect();
}