在定义表单的某些元组结构时,我有几个宏来减少样板:
macro_rules! new_type (($name:ident, $bytes:expr) => (
pub struct $name(pub [u8; $bytes]);
// some common operations on $name
));
Run Code Online (Sandbox Code Playgroud)
但是,我还要记录这些新结构.如果我能在宏调用之前编写我的文档,最好的事情就是.
/// A certain type
new_type!(CertainType, 42);
Run Code Online (Sandbox Code Playgroud)
但是,Rust不会生成CertainType
发生这种情况的文档.
另一种(不那么灵活)替代方案是做类似的事情:
macro_rules! new_type (($name:ident, $bytes:expr) => (
/// Some more generic documentation for $name
pub struct $name(pub [u8; $bytes]);
// some common operations on $name
));
Run Code Online (Sandbox Code Playgroud)
但是,在执行此操作时,Rust宏系统不会$name
在文档注释中展开令牌.剩下的唯一选择是在宏中编写非常通用的文档,但这会导致我的库文档记录得比它更糟糕.
您对此有何建议?对我来说最好的解决方案是能够为每个宏调用编写特定的文档,但如果不可能,我会很感激有关如何在文档注释中扩展标记的提示.
我有一个结构
struct Foo<'a> {
buf: [u8, ..64],
slice: &'a [u8]
}
Run Code Online (Sandbox Code Playgroud)
切片应该指向buf
结构的字段.有没有办法构建这样的结构?就像是:
impl<'a> Foo<'a> {
fn new() -> Foo<'a> {
Foo {
buf: [0, ..64],
slice: ???? /* I don't know what to write here */
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试执行类似下面的操作,则借用检查器会(正确地)抱怨,因为切片的生命周期将比结构更短.
impl<'a> Foo<'a> {
fn new() -> Foo<'a> {
let buf = [0, ..64];
Foo {
buf: buf,
slice: buf.slice_from(0)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我意识到,对于这个简单的情况,我可以保留偏移量并手动调用切片函数:
struct Foo {
buf: [u8, ..64],
slice_from: uint,
slice_to: uint
}
Run Code Online (Sandbox Code Playgroud)
然而,这个问题只是对拥有数据的结构的更一般用例的简化,并且引用了相同的数据,我想知道在Rust中是否可以(以安全的方式).
我目前正在编写绑定到加密库,该库公开了生成密钥对的函数:
const size_t PUBLICKEYBYTES = 32;
const size_t SECRETKEYBYTES = 32;
int random_keypair(unsigned char pk[PUBLICKEYBYTES],
unsigned char sk[SECRETKEYBYTES]);
Run Code Online (Sandbox Code Playgroud)
此函数随机生成一个密钥,计算相应的公钥并将结果放入pk
和sk
.
当刚刚返回一个ByteString
我发现,最简单的方法是使用create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString
从Data.ByteString.Internal
.但是,该功能不能同时创建两个ByteStrings
.
我的第一个方法是写下这样的东西:
newtype PublicKey = PublicKey ByteString
newtype SecretKey = SecretKey ByteString
randomKeypair :: IO (PublicKey, SecretKey)
randomKeypair = do
let pk = B.replicate 0 publicKeyBytes
sk = B.replicate 0 secretKeyBytes
B.unsafeUseAsCString pk $ \ppk ->
B.unsafeUseAsCString sk …
Run Code Online (Sandbox Code Playgroud) 我有一个结构定义像
struct Foo<'a> {
field1: &'a str,
field2: &'a str,
field3: &'a u8,
// ...
}
Run Code Online (Sandbox Code Playgroud)
我用来从mmap
ped文件返回解析结果.对于一些成功的解析,我想存储结果以供稍后处理,并且由于各种原因,处理将在内存释放后发生.我可以做点什么
struct OwnedFoo {
field1: String,
field2: String,
field3: Vec<u8>,
// ...
}
Run Code Online (Sandbox Code Playgroud)
并手动转换Foo
我感兴趣的所有内容OwnedFoos
.但是我想知道我是否可以这样做:
struct Foo<'a> {
field1: Cow<'a, str>,
field2: Cow<'a, str>,
field3: Cow<'a, u8>,
...
}
Run Code Online (Sandbox Code Playgroud)
相反,如果有任何方法可以自动使所有Cow
s拥有并擦除生命周期参数.我没有在图书馆文档中找到任何适用的内容.
就像是:
let a = Foo { ... };
let a_owned = a.into_owned();
// do stuff with a_owned that I can't do with a
Run Code Online (Sandbox Code Playgroud)