【译】Rust中的Sizedness (三)

531 阅读2分钟

原文链接: https://github.com/pretzelhammer/rust-blog/blob/master/posts/sizedness-in-rust.md

原文标题: Sizedness in Rust

公众号: Rust碎碎念

不确定大小类型(Unsized Types)

切片(Slices)

最常见的切片是字符串切片&str和数组切片&[T]。切片的好处在于许多其他类型能够强制转换成切片,所以利用切片和Rust的自动类型强制转换(Type coercions)能够让我们写出灵活的API。

类型强制转换(type coercions)可以在几种情况下发生但是主要发生在方法调用的函数参数上。我们感兴趣的一类类型强制转换是解引用强制转换(deref coercions)和不确定大小强制转换(unsized coercions)。一个解引用强制类型转换是在解引用操作之后,T强制转换到U,即,T:Deref<Target=U>,例如:String.deref() -> str。一个不确定大小强制转换(unsized coercion)是一个确定大小类型(sized type)的T强制转换为一个不确定大小类型(unsized type)的U,即,T:Unsized<U>,例如,[i32;3]->[i32]

trait Trait {
    fn method(&self) {}
}

impl Trait for str {
    // can now call "method" on
    // 1) str or
    // 2) String since String: Deref<Target = str>
}
impl<T> Trait for [T] {
    // can now call "method" on
    // 1) any &[T]
    // 2) any U where U: Deref<Target = [T]>, e.g. Vec<T>
    // 3) [T; N] for any N, since [T; N]: Unsize<[T]>
}

fn str_fun(s: &str) {}
fn slice_fun<T>(s: &[T]) {}

fn main() {
    let str_slice: &str = "str slice";
    let string: String = "string".to_owned();

    // function args
    str_fun(str_slice);
    str_fun(&string); // deref coercion

    // method calls
    str_slice.method();
    string.method(); // deref coercion

    let slice: &[i32] = &[1];
    let three_array: [i32; 3] = [1, 2, 3];
    let five_array: [i32; 5] = [1, 2, 3, 4, 5];
    let vec: Vec<i32> = vec![1];

    // function args
    slice_fun(slice);
    slice_fun(&vec); // deref coercion
    slice_fun(&three_array); // unsized coercion
    slice_fun(&five_array); // unsized coercion

    // method calls
    slice.method();
    vec.method(); // deref coercion
    three_array.method(); // unsized coercion
    five_array.method(); // unsized coercion
}

关键点(Key Takeaway)

  • 利用切片(slice)和Rust的自动类型强制转换能够让我们写出灵活的API

本文禁止转载,谢谢配合!欢迎关注我的微信公众号: Rust碎碎念

Rust碎碎念
Rust碎碎念