我刚开始接触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)
答案 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();
}