< 返回我的博客

wspsxing 发表于 2018-02-23 17:17

Tags:自引用, transmute

勉强(强行)没有破坏生命周期检查。

fn main() {
    let x = {
        let h = StringRef::new("HenTai!");
        println!("{:?}", h.components());
       // 下一句非法
       // h.components()
    };
    println!("{:?}", x);
}

use std::mem;

#[derive(Debug)]
struct StringRef {
    raw: String,
    components: Vec<&'static str>,
}
impl StringRef {
    fn new<S: Into<String>>(raw: S) -> Self {
        let raw = raw.into();
        let sref = unsafe {
            mem::transmute::<Vec<&str>, Vec<&'static str>>(
                raw.split('/')
                    .filter(|c| !c.trim().is_empty())
                    .collect::<Vec<&str>>(),
            )
        };
        Self {
            raw: raw,
            components: sref,
        }
    }
    fn components<'a>(&'a self) -> &'a Vec<&'a str> {
        unsafe { mem::transmute::<&Vec<&str>, &Vec<&'a str>>(&self.components) }
    }
}

评论区

写评论
作者 wspsxing 2018-02-23 19:41

@ChaosBot 提到了这个https://github.com/jpernst/rental ,但是不会用,编译不过。

不过transmut也够用了,只读结构+只开放function就行。。

作者 wspsxing 2018-02-23 19:27

这样的结构(StringRef<'a>)一部分在(let s=String::from("hello"); let h = StringRef::new(&s);),根本不是自引用,也不能Send..

@Polar 既然new确定是需要string,其实可以直接传&str就可以了,如下,就没有自引用的问题了。 感觉这里要是自引用的话,drop check过不去。 #[derive(Debug)] struct StringRef<'a> { raw: String, components: Vec<&'a str>, }

impl <'a> StringRef<'a> { fn new(s: &'a str) -> Self { let raw = s.into(); let sref =s.split('/') .filter(|c| !c.trim().is_empty()) .collect::<Vec<&'a str>>();

    Self {
        raw: raw,
        components: sref,
    }
}
fn components (&self) -> &Vec<&str> {
    &self.components
}

}

fn main() { let s=String::from("hello"); let h = StringRef::new(&s);

let x = {

    println!("{:?}", h.components());
    // 下一句非法
     h.components()
};
println!("{:?}", x);

}

Polar 2018-02-23 19:13

既然new确定是需要string,其实可以直接传&str就可以了,如下,就没有自引用的问题了。 感觉这里要是自引用的话,drop check过不去。

#[derive(Debug)]
struct StringRef<'a> {
    raw: String,
    components: Vec<&'a str>,
}

impl <'a> StringRef<'a> {
    fn new(s: &'a str) -> Self {
        let raw = s.into();
        let sref =s.split('/')
            .filter(|c| !c.trim().is_empty())
            .collect::<Vec<&'a str>>();


        Self {
            raw: raw,
            components: sref,
        }
    }
    fn components (&self) -> &Vec<&str> {
        &self.components
    }
}


fn main() {
    let s=String::from("hello");
    let h = StringRef::new(&s);

    let x = {

        println!("{:?}", h.components());
        // 下一句非法
         h.components()
    };
    println!("{:?}", x);
}
1 共 3 条评论, 1 页