一个棘手的问题是,如果没有不安全的块,就不可能解决这个问题,那就是在一个结构中引用这个结构的其他属性所拥有的东西。
然而,对于不安全的块,这很容易,你可以这样做:
struct Foo {
bar: &'static str,
foo: String
}
impl Foo {
pub fn new(s: String) -> Foo {
Foo {
bar: unsafe { ::std::mem::transmute(&s[..]) },
foo: s
}
}
}
问题是:假设之前定义的结构Foo
的方法没有给&mut
访问它的权限(因此结构在创建后永远不会被修改),知道String
的数据是堆分配的,那么这段代码实际上是安全的吗(根据rust的“安全”含义)?如果没有,在哪些情况下可能出现问题?
1条答案
按热度按时间gwo2fgha1#
&mut
访问并不重要。重要的是String
永远不会改变(至少&'static str
不会改变),其他数据可以改变。此外,如果&mut
允许第三方代码更改字符串,那么他们也可以通过继承的可变性在没有指针的情况下更改它:因此,至少您必须保持属性私有,并审计同一模块中的所有代码(不仅仅是
impl Foo
!)。但还有另一个问题:如果你 * 曾经 * 分发&'static str
,那么是的,它是不安全的:所以你能安全地用这种自我参照做的事情是非常有限的。第二个问题,* 也许 *,可以通过适当地使用生命期来避免,但是这进入了一个领域,在这个领域中,我不愿意在没有详细的半正式论证的情况下接受安全性。
对于我想象的用例,咬紧牙关远离
unsafe
可能更容易。