美文网首页
rust--Sized和UnSized

rust--Sized和UnSized

作者: 极光火狐狸 | 来源:发表于2018-09-14 18:12 被阅读49次
// 什么是Sized?


// Sized是Rust再编译阶段检查对象操作的一个基本依据,
// Rust只允许操作已知大小的对象, 未知大小的对象只能操作它的指针(&).


fn sized_correct() {
    #[derive(Debug)]
    struct Water<T>(T);            // 等同于 struct Status<T: Sized>(T);

    #[derive(Debug)]
    struct Cup(Water<i32>);

    let water = Water(10);
    let cup = Cup(water);
    println!("{:?}", cup);         // output: Cup(Water(10))
}


// 问题代码, 需要注释掉才能运行.
//fn sized_error() {
//    #[derive(Debug)]
//    struct Water<T>(T);            // 等同于 struct Status<T: Sized>(T);
//
//    #[derive(Debug)]
//    struct Cup(Water<[i32]>);     // 由于[i32] 是一个队列, 因此它是未知大小
//}


fn use_unsized_to_fix_sized_error() {
    #[derive(Debug)]
    #[allow(dead_code)]
    struct Bar<T: ?Sized>(T);

    #[derive(Debug)]
    #[allow(dead_code)]
    struct BarUse<'a>(Bar<&'a [i32]>);
}


fn thinking() {
    #[derive(Debug)]
    #[allow(dead_code)]
    struct Bar<T: ?Sized>(T);

    #[derive(Debug)]
    #[allow(dead_code)]
    struct BarUse<'a>(Bar<&'a [i32]>);
    // 备注: 虽然这里可以定义Bar<[i32]> ,
    //       但是实际上实现起来不能直接写slice, 因为编译器不允许未知大小的东西编译通过,
    //       解决办法是改成&[i32]

    let s = [1,2,3,4];
    let bar = Bar(&s[0..2]);
    let bu = BarUse(bar);
    println!("{:?}", bu);
    // 写成这样能运行的原因是, &s[0..2]是一个引用, 引用就是一个指针, 指针是固定大小的.
    // 如果指针是固定大小的, 那么上面定义的?Sized对于这个例子来说就没有意义了.
    // 这个问题我现在的水平还无法解决, 等以后水平不断深入在来解决把, 先留个TODO
    // TODO: FIXME.
}


fn main() {
    sized_correct();
    // sized_error();
    use_unsized_to_fix_sized_error();
    thinking();
}

相关文章

网友评论

      本文标题:rust--Sized和UnSized

      本文链接:https://www.haomeiwen.com/subject/txqagftx.html