Rust标准库
std::thread
Rust 通过 spawn 函数提供了创建本地操作系统(native OS)线程的机制,该函数的参数是一个转移闭包(moving closure)。
Rust默认会开4个线程,新开的线程另算。
use std::thread;
static NTHREADS: i32 = 10;
// 这是主(`main`)线程
fn main() {
// 提供一个 vector 来存放所创建的子线程(children)。
let mut children = vec![];
for i in 0..NTHREADS {
// 启动(spin up)另一个线程
children.push(thread::spawn(move || {
println!("this is thread number {}", i)
}));
}
for child in children {
// 等待线程到结束。返回一个结果。
let _ = child.join();
}
}
std::sync::mpsc
Rust 针对线程之间的通信提供了异步的通道(channel)。通道允许两个端点之间信息的单向流动:Sender(发送端) 和 Receiver(接收端)。
use std::thread;
use std::sync::mpsc::channel;
// Create a shared channel that can be sent along from many threads
// where tx is the sending half (tx for transmission), and rx is the receiving
// half (rx for receiving).
let (tx, rx) = channel();
for i in 0..10 {
let tx = tx.clone();
thread::spawn(move|| {
tx.send(i).unwrap();
});
}
for _ in 0..10 {
let j = rx.recv().unwrap();
assert!(0 <= j && j < 10);
}
path
功能有限
use std::path::Path;
fn main() {
// 从 `&'static str` 创建一个 `Path`
let path = Path::new(".");
let path = path.canonicalize().unwrap();
println!("abs: {:?} {:?}",path.is_absolute(), path.as_path());
println!("{:?}", path.parent().unwrap());
}
还有读写操作
static LOREM_IPSUM: &'static str =
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
";
use std::error::Error;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
fn main() {
let path = Path::new("out/lorem_ipsum.txt");
let display = path.display();
// 以只写模式打开文件,返回 `io::Result<File>`
let mut file = match File::create(&path) {
Err(why) => panic!("couldn't create {}: {}",
display,
why.description()),
Ok(file) => file,
};
// 将 `LOREM_IPSUM` 字符串写进 `file`,返回 `io::Result<()>`
match file.write_all(LOREM_IPSUM.as_bytes()) {
Err(why) => {
panic!("couldn't write to {}: {}", display,
why.description())
},
Ok(_) => println!("successfully wrote to {}", display),
}
}
std::process
use std::process::Command;
fn main() {
let output = Command::new("rustc")
.arg("--help")
.output().unwrap_or_else(|e| {
panic!("failed to execute process: {}", e)
});
if output.status.success() {
let s = String::from_utf8_lossy(&output.stdout);
print!("rustc succeeded and stdout was:\n{}", s);
} else {
let s = String::from_utf8_lossy(&output.stderr);
print!("rustc failed and stderr was:\n{}", s);
}
}
``
# fs
```rust
use std::fs;
use std::fs::{File, OpenOptions};
use std::io;
use std::io::prelude::*;
use std::path::Path;
// `% cat path` 的简单实现
fn cat(path: &Path) -> io::Result<String> {
let mut f = r#try!(File::open(path));
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
// `% echo s > path` 的简单实现
fn echo(s: &str, path: &Path) -> io::Result<()> {
let mut f = r#try!(File::create(path));
f.write_all(s.as_bytes())
}
// `% touch path`(忽略已存在文件)的简单实现
fn touch(path: &Path) -> io::Result<()> {
match OpenOptions::new().create(true).write(true).open(path) {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
fn main() {
println!("`mkdir a`");
// 创建一个目录,返回 `io::Result<()>`
match fs::create_dir("a") {
Err(why) => println!("! {:?}", why.kind()),
Ok(_) => {}
}
println!("`echo hello > a/b.txt`");
// 前面的匹配可以用 `unwrap_or_else` 方法简化
echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`mkdir -p a/c/d`");
// 递归创建一个目录,返回 `io::Result<()>`
fs::create_dir_all("a/c/d").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`touch a/c/e.txt`");
touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`ln -s ../b.txt a/c/b.txt`");
// 创建一个符号链接,返回 `io::Resutl<()>`
fs::soft_link("../b.txt", "a/c/b.txt").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`cat a/c/b.txt`");
match cat(&Path::new("a/c/b.txt")) {
Err(why) => println!("! {:?}", why.kind()),
Ok(s) => println!("> {}", s),
}
println!("`ls a`");
// 读取目录的内容,返回 `io::Result<Vec<Path>>`
match fs::read_dir("a") {
Err(why) => println!("! {:?}", why.kind()),
Ok(paths) => for path in paths {
println!("> {:?}", path.unwrap().path());
},
}
println!("`rm a/c/e.txt`");
// 删除一个文件,返回 `io::Result<()>`
fs::remove_file("a/c/e.txt").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`rmdir a/c/d`");
// 移除一个空目录,返回 `io::Result<()>`
fs::remove_dir("a/c/d").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
}
env
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
println!("I got {:?} arguments: {:?}.", args.len() - 1, &args[1..]);
println!("cur dir: {:?}", env::current_dir().unwrap());
println!("cur exe: {:?}", env::current_exe().unwrap());
for v in env::vars() {
println!("{:?}", v);
}
}
extern
use std::fmt;
// 此外部代码块链接到 libm 库
#[link(name = "m")]
extern {
fn ccosf(z: Complex) -> Complex;
}
// 安全装包(原文:safe wrapper)
fn cos(z: Complex) -> Complex {
unsafe { ccosf(z) }
}
fn main() {
// z = 0 + 1i
let z = Complex { re: 0., im: 1. };
println!("cos({:?}) = {:?}", z, cos(z));
}
// 最小化实现单精度复数
#[repr(C)]
#[derive(Clone, Copy)]
struct Complex {
re: f32,
im: f32,
}
impl fmt::Debug for Complex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.im < 0. {
write!(f, "{}-{}i", self.re, -self.im)
} else {
write!(f, "{}+{}i", self.re, self.im)
}
}
}