1. rust std依赖libc crate

比如io的read方法, fs的最底层的实现是

impl FileDesc {
    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        let ret = cvt(unsafe {
            libc::read(
                self.as_raw_fd(),
                buf.as_mut_ptr() as *mut libc::c_void,
                cmp::min(buf.len(), READ_LIMIT),
            )
        })?;
        Ok(ret as usize)
    }
}

这里面的libc是个"外部"crate, 但其实也是rust team维护的: https://github.com/rust-lang/libc

在rust std库的cargo.toml里面有依赖libc的声明:

[dependencies]
alloc = { path = "../alloc" }
cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.143", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.92" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
hashbrown = { version = "0.13", default-features = false, features = ['rustc-dep-of-std'] }
std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] }

# Dependencies of the `backtrace` crate
addr2line = { version = "0.18.0", optional = true, default-features = false }
rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] }
miniz_oxide = { version = "0.6.0", optional = true, default-features = false }

2. structopt

structopt用来把命令行参数转成结构体 定义结构体的时候, 用structopt来"标记", 比如:

#[derive(Clone, Debug, StructOpt)]
#[structopt(name = "virtiofsd backend", about = "Launch a virtiofsd backend.")]
struct Opt {
    /// Shared directory path
    #[structopt(long)]
    shared_dir: Option<String>,

    /// vhost-user socket path [deprecated]
    #[structopt(long, required_unless_one = &["fd", "socket-path", "print-capabilities"])]
    socket: Option<String>,

    /// vhost-user socket path
    #[structopt(long = "socket-path", required_unless_one = &["fd", "socket", "print-capabilities"])]
    socket_path: Option<String>,
    ...
}
  • 三斜线的注释会变成--help里面的option的说明, 输出格式还挺整齐的. -h的显示会更简洁一些, 只包括注释的第一行.
  • 变量下划线会变成中横线, 比如shared_dir会在--help下显示--shared-dir <shared-dir> Shared directory path

使用的时候, 比如在main里面:

fn main() {
    let opt = Opt::from_args()
}

注: structopt已经停止开发, 建议使用clap: Command Line Argument Parser for Rust

3. log

https://crates.io/crates/log 要在cargo.toml里面声明依赖:

[dependencies]
log = "0.4"

这个库设计的很合理. 对用户提供几个log的宏: error!, warn!, info!, debug! and trace!

  • lib里面, 只使用这几个输出宏
  • bin里面, 负责初始化后端的logging实现, 如果没有初始化, 那上面的几个输出宏就类似noop

可选的logging实现有:

3.1. env_logger

比如这样在代码里:

use log::{debug, error, log_enabled, info, Level};

env_logger::init();

debug!("this is a debug {}", "message");
error!("this is printed by default");

if log_enabled!(Level::Info) {
    let x = 3 * 4; // expensive computation
    info!("the answer was: {}", x);
}

使用时:

$ RUST_LOG=debug ./main
[2017-11-09T02:12:24Z DEBUG main] this is a debug message
[2017-11-09T02:12:24Z ERROR main] this is printed by default
[2017-11-09T02:12:24Z INFO main] the answer was: 12

可以按module来指定level

$ RUST_LOG=main=info ./main
[2017-11-09T02:12:24Z ERROR main] this is printed by default
[2017-11-09T02:12:24Z INFO main] the answer was: 12

又比如在virtiofsd里面是这样用的:

fn set_default_logger(log_level: LevelFilter) {
    if env::var("RUST_LOG").is_err() {
        env::set_var("RUST_LOG", log_level.to_string());
    }
    env_logger::init();
}

4. 常用宏1

代码在lib/rustlib/src/rust/library/std/src/macros.rs

  • panic
  • print
  • println
  • eprint
  • eprintln
  • dbg

5. 常用宏2

代码在lib/rustlib/src/rust/library/core/src/macros/mod.rs

  • panic!
    panic!();
    panic!("this is a {} {message}", "fancy", message = "message");
    
  • assert_eq! assert_ne!
    assert_eq!(a, b); // a b是两个表达式
    assert_ne!(a, b);
    
  • assert_matches!
    assert_matches!(a, Some(_));
    assert_matches!(b, None);
    let c = Ok("abc".to_string());
    assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
    
  • debug_assert! debug_assert_eq! debug_assert_ne! 只有在debug版本里才使能
    debug_assert!(true);
    
  • matches!
    let foo = 'f';
    assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
    let bar = Some(4);
    assert!(matches!(bar, Some(x) if x > 2));
    
  • ?和r#try!
    try!是个宏, 但需要用raw方式来调用, r#try. 现在可以用?来代替
    enum MyError {
      FileWriteError
    }
    impl From<io::Error> for MyError {
      fn from(e: io::Error) -> MyError {
          MyError::FileWriteError
      }
    }
    // The preferred method of quick returning Errors
    fn write_to_file_question() -> Result<(), MyError> {
      let mut file = File::create("my_best_friends.txt")?;
      file.write_all(b"This is a list of my best friends.")?;
      Ok(())
    }
    // The previous method of quick returning Errors
    fn write_to_file_using_try() -> Result<(), MyError> {
      let mut file = r#try!(File::create("my_best_friends.txt"));
      r#try!(file.write_all(b"This is a list of my best friends."));
      Ok(())
    }
    
  • write! writeln! 写入buffer
    fn main() -> std::io::Result<()> {
      let mut w = Vec::new();
      write!(&mut w, "test")?;
      write!(&mut w, "formatted {}", "arguments")?;
      assert_eq!(w, b"testformatted arguments");
      Ok(())
    }
    let mut s = String::new();
    writeln!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
    
  • unreachable! unimplemented! todo! 代码实现阶段用到的宏

5.1. 由编译器实现的builtin宏

  • compile_error!
    #[cfg(not(any(feature = "foo", feature = "bar")))]
    compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.");
    
  • format_args! const_format_args! format_args_nl! 格式化宏, 用于format!宏
  • env! option_env! 在编译时获取env, 注意不是运行时
    let path: &'static str = env!("PATH");
    let key: Option<&'static str> = option_env!("SECRET_KEY");
    
  • concat_idents! 多个标识符连起来成为一个
    fn foobar() -> u32 { 23 }
    let f = concat_idents!(foo, bar);
    println!("{}", f());
    
  • concat_bytes! 连接字符
  • concat!
    let s = concat!("test", 10, 'b', true);
    assert_eq!(s, "test10btrue");
    
  • line! column! file! 编译的文件, 行号等; module_path! module路径
    let current_line = line!();
    println!("defined on line: {}", current_line);
    
  • stringify!
    let one_plus_one = stringify!(1 + 1);
    assert_eq!(one_plus_one, "1 + 1");
    
  • include_str! 编译时从文件读入string; include_bytes! 编译时从文件读入bytes; 文件是相对当前编译文件的路径.
    //spanish.in里面是adiós
    let my_str = include_str!("spanish.in");
    assert_eq!(my_str, "adiós\n");
    
  • cfg!
    let my_directory = if cfg!(windows) {
      "windows-specific-directory"
    } else {
      "unix-directory"
    };
    
  • include! 把文件导入进来按表达式来编译
  • assert!
  • derive!
  • test
  • bench
  • global_allocator
  • cfg_accessible

6. trait Iterator

看起来只要实现了next就是个Iterator了... 其他都有默认实现, 真方便

pub trait Iterator {
    type Item;

    //需要用户实现的:
    fn next(&mut self) -> Option<Self::Item>;

    //有默认实现的:
    fn size_hint(&self) -> (usize, Option<usize>) //默认返回0, 用户要自己实现更适合自己的方法.
    fn count(self) -> usize
    fn last(self) -> Option<Self::Item>
    fn advance_by(&mut self, n: usize) -> Result<(), usize>
    fn nth(&mut self, n: usize) -> Option<Self::Item>
    fn step_by(self, step: usize) -> StepBy<Self>
    fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
    fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
    fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
    fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
    fn map<B, F>(self, f: F) -> Map<Self, F>
    fn for_each<F>(self, f: F)
    fn filter<P>(self, predicate: P) -> Filter<Self, P>
    fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
    fn enumerate(self) -> Enumerate<Self> //还是返回一个Iterator, 元素是(index, value)
    fn peekable(self) -> Peekable<Self>
    fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
    fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
    fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
    fn skip(self, n: usize) -> Skip<Self>
    fn take(self, n: usize) -> Take<Self>
    fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
    fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
    fn flatten(self) -> Flatten<Self>
    fn fuse(self) -> Fuse<Self>
    fn inspect<F>(self, f: F) -> Inspect<Self, F>
    fn by_ref(&mut self) -> &mut Self
    fn collect<B: FromIterator<Self::Item>>(self) -> B
    fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
    fn partition<B, F>(self, f: F) -> (B, B)
    fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
    fn is_partitioned<P>(mut self, mut predicate: P) -> bool
    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
    fn try_for_each<F, R>(&mut self, f: F) -> R
    fn fold<B, F>(mut self, init: B, mut f: F) -> B
    fn reduce<F>(mut self, f: F) -> Option<Self::Item>
    fn try_reduce<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<R::Output>>
    fn all<F>(&mut self, f: F) -> bool
    fn any<F>(&mut self, f: F) -> bool
    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    fn find_map<B, F>(&mut self, f: F) -> Option<B>
    fn try_find<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<Self::Item>>
    fn position<P>(&mut self, predicate: P) -> Option<usize>
    fn rposition<P>(&mut self, predicate: P) -> Option<usize>
    fn max(self) -> Option<Self::Item>
    fn min(self) -> Option<Self::Item>
    fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
    fn max_by<F>(self, compare: F) -> Option<Self::Item>
    fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
    fn min_by<F>(self, compare: F) -> Option<Self::Item>
    fn rev(self) -> Rev<Self>
    fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
    fn copied<'a, T: 'a>(self) -> Copied<Self>
    fn cloned<'a, T: 'a>(self) -> Cloned<Self>
    fn cycle(self) -> Cycle<Self>
    fn sum<S>(self) -> S
    fn product<P>(self) -> P
    fn cmp<I>(self, other: I) -> Ordering
    fn cmp_by<I, F>(mut self, other: I, mut cmp: F) -> Ordering
    fn partial_cmp<I>(self, other: I) -> Option<Ordering>
    fn partial_cmp_by<I, F>(mut self, other: I, mut partial_cmp: F) -> Option<Ordering>
    fn eq<I>(self, other: I) -> bool
    fn eq_by<I, F>(mut self, other: I, mut eq: F) -> bool
    fn ne<I>(self, other: I) -> bool
    fn lt<I>(self, other: I) -> bool
    fn le<I>(self, other: I) -> bool
    fn gt<I>(self, other: I) -> bool
    fn ge<I>(self, other: I) -> bool
    fn is_sorted(self) -> bool
    fn is_sorted_by<F>(mut self, compare: F) -> bool
    fn is_sorted_by_key<F, K>(self, f: F) -> bool
}

6.1. 比较常用的Iterator方法

  • filter: 对Self的关联类型的借用&Self::Item调用闭包函数, 返回另一个Iterator
  • map: 也是返回另一个Iterator
  • 最后collect: 把Iterator"重组"成一个collect对象.

6.2. collect

filter在前面讲过. 这里看一下collect:

collect基础用法如下:

let a = [1, 2, 3];

let doubled: Vec<i32> = a.iter()
                         .map(|&x| x * 2)
                         .collect();

assert_eq!(vec![2, 4, 6], doubled);

注意, 目标变量doubled需要显式指定类型, 要不然collect不知道你要"重组"成什么样的collect对象. 常用的就是collect成Vec.

下面是Iterator的默认collect实现:

//这里面很晦涩, collect返回一个泛型B, 这个B是要满足`FromIterator<Self::Item>`即Iterator的关联类型实例化的`FromIterator`
//这个B是编译器自己推断的, 或者根据左值(比如上面的let doubled: Vec<i32>), 或者用户指定, 比如更上面的.collect::<Vec<_>>();
fn collect<B: FromIterator<Self::Item>>(self) -> B
where
    Self: Sized,
{
    //这里trait名称::trait函数这个调用方式看起来无比奇怪, 有点自己调用自己的意思
    //但我理解下面的FromIterator已经是个具体的类型, 由编译器自动推导出来的:
    //比如上面的左值let doubled: Vec<i32>, 到这里就应该是调用Vec<i32>的from_iter
    FromIterator::from_iter(self)
}

//这里是说要想满足FromIterator这个trait, 就必须实现from_iter这个函数;
//而from_iter这个函数入参是个满足泛型T约束的iter, 这个T需要是个IntoIterator(一般的容器类型(collect类型)都实现了IntoIterator)
pub trait FromIterator<A>: Sized {
    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}

到这里就清楚了, 对左值let doubled: Vec<i32>的用.collect方法生成的情况, 最后调用的是Vec的from_iter()函数

impl<T> FromIterator<T> for Vec<T> {
    #[inline]
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<T> {
        <Self as SpecFromIter<T, I::IntoIter>>::from_iter(iter.into_iter())
    }
}

这里把Self转换成了SpecFromIter<T, I::IntoIter>, 实例化后是SpecFromIter<i32, I::IntoIter> 而这里的I::IntoIter其实就是变量a的类型vec<i32>的IntoIter

SpecFromIter<T, I>说的是要干一件从IntoIter I到Self的事.

pub(super) trait SpecFromIter<T, I> {
    fn from_iter(iter: I) -> Self;
}

impl<T, I> SpecFromIter<T, I> for Vec<T>
where
    I: Iterator<Item = T>,
{
    default fn from_iter(iterator: I) -> Self {
        SpecFromIterNested::from_iter(iterator)
    }
}

最后调用到:

pub(super) trait SpecFromIterNested<T, I> {
    fn from_iter(iter: I) -> Self;
}

impl<T, I> SpecFromIterNested<T, I> for Vec<T>
where
    I: Iterator<Item = T>,
{
    default fn from_iter(mut iterator: I) -> Self {
        // Unroll the first iteration, as the vector is going to be
        // expanded on this iteration in every case when the iterable is not
        // empty, but the loop in extend_desugared() is not going to see the
        // vector being full in the few subsequent loop iterations.
        // So we get better branch prediction.
        let mut vector = match iterator.next() {
            None => return Vec::new(),
            Some(element) => {
                let (lower, _) = iterator.size_hint();
                let initial_capacity =
                    cmp::max(RawVec::<T>::MIN_NON_ZERO_CAP, lower.saturating_add(1));
                let mut vector = Vec::with_capacity(initial_capacity);
                unsafe {
                    // SAFETY: We requested capacity at least 1
                    ptr::write(vector.as_mut_ptr(), element);
                    vector.set_len(1);
                }
                vector
            }
        };
        // must delegate to spec_extend() since extend() itself delegates
        // to spec_from for empty Vecs
        <Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
        vector
    }
}

6.3. IntoIterator

IntoIterator的关联类型type IntoIter是个trait, 即这个关联类型的具体类型要符合Iterator约束.

pub trait IntoIterator {
    /// The type of the elements being iterated over.
    type Item;

    /// Which kind of iterator are we turning this into?
    type IntoIter: Iterator<Item = Self::Item>;

    fn into_iter(self) -> Self::IntoIter;
}

自己实现IntoIterator

// A sample collection, that's just a wrapper over Vec<T>
#[derive(Debug)]
struct MyCollection(Vec<i32>);

// Let's give it some methods so we can create one and add things
// to it.
impl MyCollection {
    fn new() -> MyCollection {
        MyCollection(Vec::new())
    }

    fn add(&mut self, elem: i32) {
        self.0.push(elem);
    }
}

// and we'll implement IntoIterator
impl IntoIterator for MyCollection {
    type Item = i32;
    type IntoIter = std::vec::IntoIter<Self::Item>; //注意这里实例化了IntoIter类型

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

// Now we can make a new collection...
let mut c = MyCollection::new();

// ... add some stuff to it ...
c.add(0);
c.add(1);
c.add(2);

// ... and then turn it into an Iterator:
for (i, n) in c.into_iter().enumerate() {
    assert_eq!(i as i32, n);
}

比如BTreeMap就实现了into_iter的方法

impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
    type Item = (&'a K, &'a V);
    type IntoIter = Iter<'a, K, V>;

    fn into_iter(self) -> Iter<'a, K, V> {
        self.iter()
    }
}

可以看到BTreeMap的into_iter其实就是self.iter(), 反回的都是Iter<'a, K, V>这个结构体(这个结构体实现了Iterator).

7. 数组泛型的方法impl<T> [T]

数组泛型实现了多种方法, 比如join.

impl<T> [T] {
    pub fn sort(&mut self)
    where
        T: Ord,

    pub fn sort_by<F>(&mut self, mut compare: F)
    where
        F: FnMut(&T, &T) -> Ordering,

    pub fn sort_by_key<K, F>(&mut self, mut f: F)
    where
        F: FnMut(&T) -> K,
        K: Ord,

    pub fn sort_by_cached_key<K, F>(&mut self, f: F)
    where
        F: FnMut(&T) -> K,
        K: Ord,

    pub fn to_vec(&self) -> Vec<T>
    where
        T: Clone,

    pub fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A>
    where
        T: Clone,

    pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A>

    pub fn repeat(&self, n: usize) -> Vec<T>
    where
        T: Copy,

    pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
    where
        Self: Concat<Item>,

    pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
    where
        Self: Join<Separator>, //这里首先约束Self是Join<Separator>
    {
        Join::join(self, sep) //这里调用了约束的join函数. 
    }

    pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
    where
        Self: Join<Separator>,
}

但因为T是泛型, 要实现有用的方法, 比如对T进行约束. 比如join就要求[T]满足:Self: Join<Separator>

pub trait Join<Separator> {
    /// The resulting type after concatenation
    type Output;

    /// Implementation of [`[T]::join`](slice::join)
    fn join(slice: &Self, sep: Separator) -> Self::Output;
}

注意上面的Separator是泛型的类型指示符, 指代具体类型.

上面的例子非常有趣, 泛型[T]实现了join方法, 而这个join方法看起来又调用了"Self"的join.

是Self有两套join实现吗? -- 是. [T]有join方法, 没毛病. 而[V]实现了Join trait, 也实现了join函数. 如下:

impl<T: Clone, V: Borrow<[T]>> Join<&T> for [V] {
    type Output = Vec<T>;

    fn join(slice: &Self, sep: &T) -> Vec<T> {
        let mut iter = slice.iter();
        let first = match iter.next() {
            Some(first) => first,
            None => return vec![],
        };
        let size = slice.iter().map(|v| v.borrow().len()).sum::<usize>() + slice.len() - 1;
        let mut result = Vec::with_capacity(size);
        result.extend_from_slice(first.borrow());

        for v in iter {
            result.push(sep.clone());
            result.extend_from_slice(v.borrow())
        }
        result
    }
}

这是两套语义, rust并没有因为看见Self有join方法, 就像go一样, 自动推断Self实现了Join trait; 相反的, 用户需要明确声明, 我实现了Join trait(for 关键词). 这种情况下, 会同时存在两套join. 在本例中, 前者还调用了后者.

这不是多此一举吗? 一个同名的join调来调去有意思吗? --不是. 有意思. 因为Separator不同, 实际调用的Join trait也不同. 比如如果Separator是&T, 就需要实现Join<&T>的trait. 代码见上面 如果Separator是&[T], 就需要实现Join<&[T]>的trait, 如下:

impl<T: Clone, V: Borrow<[T]>> Join<&[T]> for [V] {
    type Output = Vec<T>;

    fn join(slice: &Self, sep: &[T]) -> Vec<T> {
        let mut iter = slice.iter();
        let first = match iter.next() {
            Some(first) => first,
            None => return vec![],
        };
        let size =
            slice.iter().map(|v| v.borrow().len()).sum::<usize>() + sep.len() * (slice.len() - 1);
        let mut result = Vec::with_capacity(size);
        result.extend_from_slice(first.borrow());

        for v in iter {
            result.extend_from_slice(sep);
            result.extend_from_slice(v.borrow())
        }
        result
    }
}

比如字符串的:

impl<S: Borrow<str>> Join<&str> for [S] {
    type Output = String;

    fn join(slice: &Self, sep: &str) -> String {
        unsafe { String::from_utf8_unchecked(join_generic_copy(slice, sep.as_bytes())) }
    }
}

8. Vec

Vec结构体:

pub struct Vec<T, A: Allocator = Global> {
    buf: RawVec<T, A>,
    len: usize,
}

方法:

impl<T> Vec<T> {
     pub const fn new() -> Self
     pub fn with_capacity(capacity: usize) -> Self
     pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self
}

带allocator的Vec有更多的方法:

impl<T, A: Allocator> Vec<T, A> {
    pub const fn new_in(alloc: A) -> Self
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self
    pub fn capacity(&self) -> usize
    pub fn reserve(&mut self, additional: usize)
    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
    pub fn shrink_to_fit(&mut self)
    pub fn shrink_to(&mut self, min_capacity: usize)
    pub fn into_boxed_slice(mut self) -> Box<[T], A>
    pub fn truncate(&mut self, len: usize)
    pub fn as_slice(&self) -> &[T]
    pub fn as_mut_slice(&mut self) -> &mut [T]
    pub fn as_ptr(&self) -> *const T
    pub fn allocator(&self) -> &A
    pub unsafe fn set_len(&mut self, new_len: usize)
    pub fn swap_remove(&mut self, index: usize) -> T
    pub fn insert(&mut self, index: usize, element: T)
    pub fn remove(&mut self, index: usize) -> T
    pub fn retain<F>(&mut self, mut f: F)
    pub fn dedup_by<F>(&mut self, mut same_bucket: F)
    pub fn push(&mut self, value: T)
    pub fn pop(&mut self) -> Option<T>
    pub fn append(&mut self, other: &mut Self)

    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A> //返回一个iterator, 包括range内的所有元素
    pub fn clear(&mut self) //移出所有元素
    pub fn len(&self) -> usize
    pub fn is_empty(&self) -> bool
    pub fn split_off(&mut self, at: usize) -> Self
    pub fn resize_with<F>(&mut self, new_len: usize, f: F)
    pub fn leak<'a>(self) -> &'a mut [T]

}

更具化的泛型

impl<T: Clone, A: Allocator> Vec<T, A> {
    pub fn resize(&mut self, new_len: usize, value: T)
    pub fn extend_from_slice(&mut self, other: &[T])
    pub fn extend_from_within<R>(&mut self, src: R)
}

Vec实现了解引用

impl<T, A: Allocator> ops::Deref for Vec<T, A> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
    }
}

9. Option

Option的方法如下:

impl<T> Option<T> {
    pub const fn is_some(&self) -> bool
    pub fn is_some_with(&self, f: impl FnOnce(&T) -> bool) -> bool
    pub const fn is_none(&self) -> bool
    pub const fn as_ref(&self) -> Option<&T>
    pub const fn as_mut(&mut self) -> Option<&mut T>
    pub const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>>
    pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>>

    pub const fn expect(self, msg: &str) -> T
    pub const fn unwrap(self) -> T
    pub const fn unwrap_or(self, default: T) -> T

    pub const fn map<U, F>(self, f: F) -> Option<U>
    pub const fn filter<P>(self, predicate: P) -> Self
    pub const fn inspect<F>(self, f: F) -> Self
    pub const fn ok_or<E>(self, err: E) -> Result<T, E>
    pub const fn iter(&self) -> Iter<'_, T>

    pub const fn and_then<U, F>(self, f: F) -> Option<U>
    pub const fn and<U>(self, optb: Option<U>) -> Option<U>
    pub const fn or(self, optb: Option<T>) -> Option<T>
    pub const fn or_else<F>(self, f: F) -> Option<T>
    pub const fn xor(self, optb: Option<T>) -> Option<T>
    pub const fn insert(&mut self, value: T) -> &mut T
    pub const fn get_or_insert(&mut self, value: T) -> &mut T

    pub const fn take(&mut self) -> Option<T>
    pub const fn replace(&mut self, value: T) -> Option<T>
    pub const fn contains<U>(&self, x: &U) -> bool
    pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
}

10. Result

Result是经常用的rust抽象, 用于返回值的处理, 很优雅. 代码在lib/rustlib/src/rust/library/core/src/result.rs

#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Result<T, E> {
    /// Contains the success value
    #[lang = "Ok"]
    Ok(#[stable(feature = "rust1", since = "1.0.0")] T),

    /// Contains the error value
    #[lang = "Err"]
    Err(#[stable(feature = "rust1", since = "1.0.0")] E),
}

10.1. Result的方法:

impl<T, E> Result<T, E> {
    pub const fn is_ok(&self) -> bool

    /// let x: Result<u32, &str> = Ok(2);
    /// assert_eq!(x.is_ok_with(|&x| x > 1), true);
    ///
    /// let x: Result<u32, &str> = Ok(0);
    /// assert_eq!(x.is_ok_with(|&x| x > 1), false);
    ///
    /// let x: Result<u32, &str> = Err("hey");
    /// assert_eq!(x.is_ok_with(|&x| x > 1), false);
    pub fn is_ok_with(&self, f: impl FnOnce(&T) -> bool) -> bool

    pub const fn is_err(&self) -> bool

    ///  let  x: Result<u32, Error> =  Err(Error::new(ErrorKind::NotFound, "!"));
    ///  assert_eq!(x.is_err_with(|x| x.kind() == ErrorKind::NotFound), true);
    ///
    ///  let  x: Result<u32, Error> =  Err(Error::new(ErrorKind::PermissionDenied, "!"));
    ///  assert_eq!(x.is_err_with(|x| x.kind() == ErrorKind::NotFound), false);
    ///
    ///  let  x: Result<u32, Error> =  Ok(123);
    ///  assert_eq!(x.is_err_with(|x| x.kind() == ErrorKind::NotFound), false);
    pub  fn  is_err_with(&self, f:  impl  FnOnce(&E) ->  bool) ->  bool

    pub  fn  ok(self) ->  Option<T> //把Result<T, E>转换为Option<T>

    pub  fn  err(self) ->  Option<E>

    pub const fn as_ref(&self) -> Result<&T, &E>
    pub const fn as_mut(&mut self) -> Result<&mut T, &mut E>

    //调用F把Result<T, E>转为Result<U, E>
    pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U, E>
    pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U
    pub fn map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U

    pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, F>
    pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self
    pub fn inspect_err<F: FnOnce(&E)>(self, f: F) -> Self

    /// let x: Result<String, u32> = Ok("hello".to_string());
    /// let y: Result<&str, &u32> = Ok("hello");
    /// assert_eq!(x.as_deref(), y);
    ///
    /// let x: Result<String, u32> = Err(42);
    /// let y: Result<&str, &u32> = Err(&42);
    pub fn as_deref(&self) -> Result<&T::Target, &E>
    where
        T: Deref,

    pub fn iter(&self) -> Iter<'_, T>
    pub fn iter_mut(&mut self) -> IterMut<'_, T>

    //返回Ok里面的T, 如果Error就panic
    pub fn expect(self, msg: &str) -> T
    where
        E: fmt::Debug,

    // unwrap也返回T, 也可能panic, 但似乎就没有panic message
    pub fn unwrap(self) -> T
    where
        E: fmt::Debug,

    // 也是unwrap, 但不panic, 不Ok就返回default
    pub fn unwrap_or_default(self) -> T
    where
        T: Default,

    //unwrap不panic, 不ok则返回指定的default
    pub fn unwrap_or(self, default: T) -> T

    pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T

    // 实际上是unwrap E
    pub fn expect_err(self, msg: &str) -> E
    where
        T: fmt::Debug,

    pub fn unwrap_err(self) -> E
    where
        T: fmt::Debug,

    pub fn into_ok(self) -> T
    where
        E: Into<!>,

    pub fn into_err(self) -> E
    where
        T: Into<!>,

    // and表示检测x, y中只要有Error, 就返回Error
    /// let x: Result<u32, &str> = Ok(2);
    /// let y: Result<&str, &str> = Err("late error");
    /// assert_eq!(x.and(y), Err("late error"));
    pub fn and<U>(self, res: Result<U, E>) -> Result<U, E>

    /// assert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string()));
    /// assert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number"));
    pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E>

    pub fn or<F>(self, res: Result<T, F>) -> Result<T, F>
    pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F>

    /// let x: Result<u32, &str> = Ok(2);
    /// assert_eq!(x.contains(&2), true);
    ///
    /// let x: Result<u32, &str> = Ok(3);
    /// assert_eq!(x.contains(&2), false);
    ///
    /// let x: Result<u32, &str> = Err("Some error message");
    /// assert_eq!(x.contains(&2), false);
    pub fn contains<U>(&self, x: &U) -> bool
    where
        U: PartialEq<T>,
}

注: const fn表示这个fn可以用在const上下文中

10.2. Result<&T, E>的方法

Result<&T, E>也能调用Result的方法, 比如下面copied函数中, 直接用了self.map, 因为Result是个范围很广的泛型, 自然也就包括了Result<&T, E>, 这里要把T看成是&T'

impl<T, E> Result<&T, E> {
    pub  fn  copied(self) ->  Result<T, E>
    where
        T:  Copy,
    {
        self.map(|&t|  t) //注意这里, map的F是FnOnce(T), 是针对Result<T, E>来说的; 这里应该传入"&T", 那么形式上&t就是T, 然后返回t就是返回T. 看起来挺难理解的...
    }

    pub fn cloned(self) -> Result<T, E>
    where
        T: Clone,
    {
        self.map(|t| t.clone()) //这里就没有那么绕, t就是&T
    }
}

10.3. 其他Result

impl<T, E> Result<&mut  T, E>
impl<T, E> Result<Option<T>, E>
impl<T, E> Result<Result<T, E>, E>
impl<T> Result<T, T>

10.4. Result实现了如下的trait

impl<T: Clone, E: Clone> Clone for Result<T, E> 
impl<T, E> IntoIterator for Result<T, E>
impl<'a, T, E> IntoIterator  for  &'a  Result<T, E>
impl<'a, T, E> IntoIterator  for  &'a  mut  Result<T, E>

11. env

// 这个就是golang的os.args
let args: Vec<String> = env::args().collect();

12. 取消impl trait

就是取消 取消 取消!

impl !Send for Args {}

impl !Sync for Args {}

13. 文件

lib/rustlib/src/rust/library/std/src/fs.rs

13.1. 使用举例

13.1.1. 写文件

use std::fs::File;
use std::io::prelude::*;

fn main() -> std::io::Result<()> {
    let mut file = File::create("foo.txt")?;
    file.write_all(b"Hello, world!")?;
    Ok(())
}

13.1.2. 读文件到String

use std::fs::File;
use std::io::prelude::*;

fn main() -> std::io::Result<()> {
    let mut file = File::open("foo.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    assert_eq!(contents, "Hello, world!");
    Ok(())
}

注意这里, file.read_to_string(), file对象impl Read, 有read_to_string()方法, 就在本文件; 而vscode点击进去, 却是lib/rustlib/src/rust/library/std/src/io/mod.rs中io:Read这个trait的默认实现.

13.1.3. 更有效率的读文件

use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;

fn main() -> std::io::Result<()> {
    let file = File::open("foo.txt")?;
    let mut buf_reader = BufReader::new(file);
    let mut contents = String::new();
    buf_reader.read_to_string(&mut contents)?;
    assert_eq!(contents, "Hello, world!");
    Ok(())
}

13.1.4. 不同选项open

let file = OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .open("foo.txt");

13.1.5. &File也能modify 文件

Note that, although read and write methods require a &mut File, because of the interfaces for [Read] and [Write], the holder of a &File can still modify the file, either through methods that take &File or by retrieving the underlying OS object and modifying the file that way. Additionally, many operating systems allow concurrent modification of files by different processes. Avoid assuming that holding a &File means that the file will not change.

这里是说read和write方法都要求&mut File, 但实际上, &File的持有者也可以修改文件. 这里提醒大家不要认为持有&File的人就"没危险"了, 他们也可以修改你的文件, 因为文件系统允许多进程打开一个文件.

13.2. File对象

pub struct File {
    inner: fs_imp::File,
}

还有几个"辅助"元组对象定义:

pub struct Metadata(fs_imp::FileAttr);
pub struct ReadDir(fs_imp::ReadDir);
pub struct DirEntry(fs_imp::DirEntry);
pub struct OpenOptions(fs_imp::OpenOptions);
pub struct Permissions(fs_imp::FilePermissions);
pub struct FileType(fs_imp::FileType);
pub struct DirBuilder {
    inner: fs_imp::DirBuilder,
    recursive: bool,
}

13.3. 常用函数

  • 读所有文件内容到Vec pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>>
    use std::fs;
    use std::net::SocketAddr;
    fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
      let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?;
      Ok(())
    }
    
  • 读所有文件内容到String pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String>
    use std::fs;
    use std::net::SocketAddr;
    use std::error::Error;
    fn main() -> Result<(), Box<dyn Error>> {
      let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;
      Ok(())
    }
    
  • 简单的写slice到文件 pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()>
    use std::fs;
    fn main() -> std::io::Result<()> {
      fs::write("foo.txt", b"Lorem ipsum")?; //&str可以被认为是AsRef<[u8]>
      fs::write("bar.txt", "dolor sit")?;
      Ok(())
    }
    
  • remove文件 pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()>
    use std::fs;
    fn main() -> std::io::Result<()> {
      fs::remove_file("a.txt")?;
      Ok(())
    }
    
  • metadata
    fn main() -> std::io::Result<()> {
      let attr = fs::metadata("/some/file/path.txt")?;
      // inspect attr ...
      Ok(())
    }
    
  • symlink_metadata
  • rename
  • copy
  • hard_link
  • soft_link
  • read_link
  • canonicalize 可能和abs path差不多
  • create_dir
  • create_dir_all
  • remove_dir
  • remove_dir_all
  • read_dir 例子1
    use std::io;
    use std::fs::{self, DirEntry};
    use std::path::Path;
    // one possible implementation of walking a directory only visiting files
    fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> io::Result<()> {
      if dir.is_dir() {
          for entry in fs::read_dir(dir)? {
              let entry = entry?;
              let path = entry.path();
              if path.is_dir() {
                  visit_dirs(&path, cb)?;
              } else {
                  cb(&entry);
              }
          }
      }
      Ok(())
    }
    
    例子2
    use std::{fs, io};
    fn main() -> io::Result<()> {
      let mut entries = fs::read_dir(".")?
          .map(|res| res.map(|e| e.path()))
          .collect::<Result<Vec<_>, io::Error>>()?;
      // The order in which `read_dir` returns entries is not guaranteed. If reproducible
      // ordering is required the entries should be explicitly sorted.
      entries.sort();
      // The entries have now been sorted by their path.
      Ok(())
    }
    
  • set_permissions
    use std::fs;
    fn main() -> std::io::Result<()> {
      let mut perms = fs::metadata("foo.txt")?.permissions();
      perms.set_readonly(true);
      fs::set_permissions("foo.txt", perms)?;
      Ok(())
    }
    

13.4. File的方法

impl File {
}
  • open pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File>
    use std::fs::File;
    fn main() -> std::io::Result<()> {
      let mut f = File::open("foo.txt")?;
      Ok(())
    }
    
  • create pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File>
    use std::fs::File;
    fn main() -> std::io::Result<()> {
      let mut f = File::create("foo.txt")?;
      Ok(())
    }
    
  • options pub fn options() -> OpenOptions
    use std::fs::File;
    fn main() -> std::io::Result<()> {
      let mut f = File::options().append(true).open("example.log")?;
      Ok(())
    }
    
  • sync_all 就是fsync pub fn sync_all(&self) -> io::Result<()>
    use std::fs::File;
    use std::io::prelude::*;
    fn main() -> std::io::Result<()> {
      let mut f = File::create("foo.txt")?;
      f.write_all(b"Hello, world!")?;
      f.sync_all()?;
      Ok(())
    }
    
  • sync_data 比sync_all少一些disk操作 pub fn sync_data(&self) -> io::Result<()>
    use std::fs::File;
    use std::io::prelude::*;
    fn main() -> std::io::Result<()> {
      let mut f = File::create("foo.txt")?;
      f.write_all(b"Hello, world!")?;
      f.sync_data()?;
      Ok(())
    }
    
  • set_len 设文件大小, 若原本size小, 就shrink文件到新size; 如果原size小, 则剩下的都填0
    use std::fs::File;
    fn main() -> std::io::Result<()> {
      let mut f = File::create("foo.txt")?;
      f.set_len(10)?;
      Ok(())
    }
    
  • metadata
  • try_clone
  • set_permissions

13.5. 其他impl的trait

impl AsInner<fs_imp::File> for File
impl FromInner<fs_imp::File> for File
impl IntoInner<fs_imp::File> for File
impl fmt::Debug for File

根据注释, 还实现了比如AsFd等trait. 但不知道藏在哪里实现的???

// In addition to the `impl`s here, `File` also has `impl`s for
// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and
// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.

13.6. 实现Read trait

pub struct File {
    inner: fs_imp::File,
}

这里显得很啰嗦, 基本都是调用inner的对应函数. 因为File包括了inner. 因为rust没有继承就要再写一遍wrapper吗???

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }

    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        self.inner.read_vectored(bufs)
    }

    fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
        self.inner.read_buf(buf)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        self.inner.is_read_vectored()
    }

    // Reserves space in the buffer based on the file size when available.
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        buf.reserve(buffer_capacity_required(self));
        io::default_read_to_end(self, buf)
    }

    // Reserves space in the buffer based on the file size when available.
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        buf.reserve(buffer_capacity_required(self));
        io::default_read_to_string(self, buf)
    }
}

13.7. 实现Write trait

impl Write for File {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(buf)
    }

    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
        self.inner.write_vectored(bufs)
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        self.inner.is_write_vectored()
    }

    fn flush(&mut self) -> io::Result<()> {
        self.inner.flush()
    }
}

13.8. 实现Seek trait

impl Seek for File {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        self.inner.seek(pos)
    }
}

13.9. Read Write Seek for &File又来一遍!!!!!

有意思吗?

impl Read for &File {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }

    fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
        self.inner.read_buf(buf)
    }

    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        self.inner.read_vectored(bufs)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        self.inner.is_read_vectored()
    }

    // Reserves space in the buffer based on the file size when available.
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        buf.reserve(buffer_capacity_required(self));
        io::default_read_to_end(self, buf)
    }

    // Reserves space in the buffer based on the file size when available.
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        buf.reserve(buffer_capacity_required(self));
        io::default_read_to_string(self, buf)
    }
}

13.10. open最后调用

use crate::sys::fs as fs_imp;
fn _open(&self, path: &Path) -> io::Result<File> {
        fs_imp::File::open(path, &self.0).map(|inner| File { inner })
    }

fs_imp::File::open代码在lib/rustlib/src/rust/library/std/src/sys/unix/fs.rs 里面调用了很多libc的函数.

14. IO

14.1. 常用函数

pub fn read_to_string<R: Read>(mut reader: R) -> Result<String>
//这个是内部使用的函数
fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> Result<usize>

14.2. Read trait

pub trait Read {
    /// use std::io;
    /// use std::io::prelude::*;
    /// use std::fs::File;
    ///
    /// fn main() -> io::Result<()> {
    ///     let mut f = File::open("foo.txt")?;
    ///     let mut buffer = [0; 10];
    ///
    ///     // read up to 10 bytes
    ///     let n = f.read(&mut buffer[..])?;
    ///
    ///     println!("The bytes: {:?}", &buffer[..n]);
    ///     Ok(())
    /// }
    //也是传入一个[u8]的数组, 返回大小
    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;

    //vector方式读
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
        default_read_vectored(|b| self.read(b), bufs)
    }

    //有没有vector读, 默认false
    fn is_read_vectored(&self) -> bool {
        false
    }

    /// use std::io;
    /// use std::io::prelude::*;
    /// use std::fs::File;
    ///
    /// fn main() -> io::Result<()> {
    ///     let mut f = File::open("foo.txt")?;
    ///     let mut buffer = Vec::new();
    ///
    ///     // read the whole file
    ///     f.read_to_end(&mut buffer)?;
    ///     Ok(())
    /// }
    //读完所有byte
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
        default_read_to_end(self, buf)
    }

    /// use std::io;
    /// use std::io::prelude::*;
    /// use std::fs::File;
    ///
    /// fn main() -> io::Result<()> {
    ///     let mut f = File::open("foo.txt")?;
    ///     let mut buffer = String::new();
    ///
    ///     f.read_to_string(&mut buffer)?;
    ///     Ok(())
    /// }
    //读完所有string
    fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
        default_read_to_string(self, buf)
    }

    /// use std::io;
    /// use std::io::prelude::*;
    /// use std::fs::File;
    ///
    /// fn main() -> io::Result<()> {
    ///     let mut f = File::open("foo.txt")?;
    ///     let mut buffer = [0; 10];
    ///
    ///     // read exactly 10 bytes
    ///     f.read_exact(&mut buffer)?;
    ///     Ok(())
    /// }
    //一直读到size
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
        default_read_exact(self, buf)
    }

    //read到ReadBuf
    fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
        default_read_buf(|b| self.read(b), buf)
    }
    fn read_buf_exact(&mut self, buf: &mut ReadBuf<'_>) -> Result<()>

    //借用
    fn by_ref(&mut self) -> &mut Self

    //把这个Read转换为byte iterator
    fn  bytes(self) ->  Bytes<Self>

    /// use std::io;
    /// use std::io::prelude::*;
    /// use std::fs::File;
    ///
    /// fn main() -> io::Result<()> {
    ///     let mut f1 = File::open("foo.txt")?;
    ///     let mut f2 = File::open("bar.txt")?;
    ///
    ///     let mut handle = f1.chain(f2);
    ///     let mut buffer = String::new();
    ///
    ///     // read the value into a String. We could use any Read method here,
    ///     // this is just one example.
    ///     handle.read_to_string(&mut buffer)?;
    ///     Ok(())
    /// }
    //和next Read成链, 先读Self, 接着读next
    fn chain<R: Read>(self, next: R) -> Chain<Self, R>

    /// use std::io;
    /// use std::io::prelude::*;
    /// use std::fs::File;
    ///
    /// fn main() -> io::Result<()> {
    ///     let mut f = File::open("foo.txt")?;
    ///     let mut buffer = [0; 5];
    ///
    ///     // read at most five bytes
    ///     let mut handle = f.take(5);
    ///
    ///     handle.read(&mut buffer)?;
    ///     Ok(())
    /// }
    //返回一个新的Read, 但只读limit字节
    fn take(self, limit: u64) -> Take<Self>
}

14.3. Write trait

pub  trait  Write {
    //很自然的, 这里的buf是个借用
    //和read一样, write也可以部分写
    fn write(&mut self, buf: &[u8]) -> Result<usize>;
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize>
    fn is_write_vectored(&self) -> bool
    //这个flush是write独有的
    fn flush(&mut self) -> Result<()>;

    //全写
    fn write_all(&mut self, mut buf: &[u8]) -> Result<()>

    fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()>
    //写格式化string到Write
    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()>

    fn by_ref(&mut self) -> &mut Self
}

14.4. Seek trait

pub trait Seek {
    fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
    //从头开始
    fn rewind(&mut self) -> Result<()>
    //返回这个stream的字节数
    fn stream_len(&mut self) -> Result<u64>
    //stream的当前位置
    fn stream_position(&mut self) -> Result<u64>
}

14.5. BufRead是Read的派生trait

BufRead自带内部buffer 比如stdin.lock()就实现了BufRead

use std::io;
use std::io::prelude::*;
let stdin = io::stdin();
for line in stdin.lock().lines() {
    println!("{}", line.unwrap());
}

比如可以用BufReader::new(r)把Reader r转换为BufReader

use std::io::{self, BufReader};
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let f = File::open("foo.txt")?;
    let f = BufReader::new(f);

    for line in f.lines() {
        println!("{}", line.unwrap());
    }

    Ok(())
}

下面是BufRead的定义:

pub trait BufRead: Read {
    //读出内部buffer, 并从内部reader填入新数据
    fn fill_buf(&mut self) -> Result<&[u8]>;
    //amt数量的字节已经被consume了
    fn consume(&mut self, amt: usize);
    fn has_data_left(&mut self) -> Result<bool>

    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize>

    fn read_line(&mut self, buf: &mut String) -> Result<usize>

    //返回一个按照分隔符byte分割的iterator
    fn split(self, byte: u8) -> Split<Self>

    //返回按行分隔的iterator
    fn lines(self) -> Lines<Self>
}

results matching ""

    No results matching ""