安全地从流中读取结构的辅助函数
Helper function to safely read structure from stream
假设我们有一个 OS 的单个地址 space。为了保持稳定性,我们需要为用户应用程序强制内存保护,例如禁止使用 'unsafe' 关键字,除非用户具有特殊能力。
我们的用户需要有一种方法来安全地 read/write 任意结构 from/to 字节流(例如文件)。当然,我们讨论的是不包含引用的结构(否则我们会失去内存安全)。
现在我尝试实现这种通用的 reader 函数:
#![feature(core)]
use std::io;
use std::mem;
use std::raw;
fn read<T>(reader: &mut io::Read, dest: &mut T) -> io::Result<usize> {
let slice = raw::Slice{ data:dest, len:mem::size_of::<T>() };
let buf: &mut [u8] = unsafe { mem::transmute(slice) };
reader.read(buf)
}
上面的实现有严重的问题。它允许读取包含引用的结构。那么我该如何解决呢?
您可以使用所谓的 "Marker Trait":一个自定义的不安全特性,它具有适用于所有类型的默认 impl 和适用于所有引用的负面特性 impl。由于您禁止 unsafe
的所有使用,用户不能自己实现该特征,因此不能为任何具有引用的类型实现该特征。
您可能还应该在负面影响中包含原始指针(*mut
和 *const
)...否则用户可能会反序列化 Vec
或其他一些 "safe" 具有内在不安全性的类型。
#![feature(optin_builtin_traits)]
unsafe trait NoInnerRefs {}
impl<'a, T> !NoInnerRefs for &'a T {}
unsafe impl NoInnerRefs for .. {}
struct A(&'static str);
struct B(i32);
fn test<T: NoInnerRefs>(_: T) {
}
fn main() {
test(B(5));
test(A("hi"));
}
这将无法编译:
<anon>:17:5: 17:9 error: the trait `NoInnerRefs` is not implemented for the type `&'static str` [E0277]
<anon>:17 test(A("hi"));
^~~~
假设我们有一个 OS 的单个地址 space。为了保持稳定性,我们需要为用户应用程序强制内存保护,例如禁止使用 'unsafe' 关键字,除非用户具有特殊能力。
我们的用户需要有一种方法来安全地 read/write 任意结构 from/to 字节流(例如文件)。当然,我们讨论的是不包含引用的结构(否则我们会失去内存安全)。
现在我尝试实现这种通用的 reader 函数:
#![feature(core)]
use std::io;
use std::mem;
use std::raw;
fn read<T>(reader: &mut io::Read, dest: &mut T) -> io::Result<usize> {
let slice = raw::Slice{ data:dest, len:mem::size_of::<T>() };
let buf: &mut [u8] = unsafe { mem::transmute(slice) };
reader.read(buf)
}
上面的实现有严重的问题。它允许读取包含引用的结构。那么我该如何解决呢?
您可以使用所谓的 "Marker Trait":一个自定义的不安全特性,它具有适用于所有类型的默认 impl 和适用于所有引用的负面特性 impl。由于您禁止 unsafe
的所有使用,用户不能自己实现该特征,因此不能为任何具有引用的类型实现该特征。
您可能还应该在负面影响中包含原始指针(*mut
和 *const
)...否则用户可能会反序列化 Vec
或其他一些 "safe" 具有内在不安全性的类型。
#![feature(optin_builtin_traits)]
unsafe trait NoInnerRefs {}
impl<'a, T> !NoInnerRefs for &'a T {}
unsafe impl NoInnerRefs for .. {}
struct A(&'static str);
struct B(i32);
fn test<T: NoInnerRefs>(_: T) {
}
fn main() {
test(B(5));
test(A("hi"));
}
这将无法编译:
<anon>:17:5: 17:9 error: the trait `NoInnerRefs` is not implemented for the type `&'static str` [E0277]
<anon>:17 test(A("hi"));
^~~~