如何连接以下类型组合:
str 和 strString 和 strString 和 String我正在使用Rust中的宏并希望进行嵌套扩展,即组合.
这是我写的代码:
macro_rules! nested {
(
$(arg $arg:ident;)*
$(fun $fun:ident;)*
) => {
$(
$fun($($arg),*);
)*
}
}
fn show1(a: i32, b: i32, c: i32) {
println!("show1: {} {} {}", a, b, c);
}
fn show2(a: i32, b: i32, c: i32) {
println!("show2: {} {} {}", a, b, c);
}
fn main() {
let a = 1;
let b = 2;
let c = 3;
nested! {
arg a;
arg b;
arg c;
fun show1;
fun show2;
}
}
Run Code Online (Sandbox Code Playgroud)
在Rust中有一种自然的方法来迭代几个范围或迭代器的"产品"吗?
当您在多维数组或某些状态空间上进行迭代时,会出现这种情况.例如,我想考虑具有5个元素的布尔元组的所有可能值.嵌套5个for循环有点笨拙.
我创建了一个最小的例子来说明我无法解决的类型推断问题.
trait A<'a> {
type Item: Copy;
type Iter: Iterator<Item=Self::Item>;
fn items(&'a self) -> Self::Iter;
fn consume(&'a self, i: Self::Item) -> Self::Item;
fn f(&'a self) {
let _ = self.items().map(|i| self.consume(i) as Self::Item);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器错误是
x.rs:10:30: 10:68 error: type annotations required: cannot resolve `<<Self as A<'_>>::Iter as core::iter::Iterator>::Item == _` [E0284]
x.rs:10 let _ = self.items().map(|i| self.consume(i) as Self::Item);
Run Code Online (Sandbox Code Playgroud)
我已经查看了有关要求类型注释的其他问题,但这似乎是涉及相关类型的特殊情况.
我正在尝试使这个简单的代码编译:
fn dox(x: u8) -> u8 { x*2 }
fn main() {
let cb: &'static (Fn(u8) -> u8) = &dox;
}
Run Code Online (Sandbox Code Playgroud)
但它失败了Rust 1.9:
x.rs:4:40: 4:43 error: borrowed value does not live long enough
x.rs:4 let cb: &'static (Fn(u8) -> u8) = &dox;
^~~
note: reference must be valid for the static lifetime...
x.rs:4:44: 5:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 4:43
x.rs:4 let cb: &'static (Fn(u8) -> u8) = &dox;
x.rs:5 …Run Code Online (Sandbox Code Playgroud) 我想拥有功能数据结构的优势(可以共享结构的多个数据版本),但能够以命令式方式修改它.
我正在考虑的(以及可能的用途):一个RPG游戏,其中存储了整个游戏历史(例如,允许回到过去).使用copy-on-write,我可以简单地克隆保持游戏状态的结构并通过引入新的转弯来修改它 - 但是可以访问较早的转弯(不一定是所有这些转弯,可能只是游戏状态的选定快照),而不是每次必须复制一切的惩罚.
让我们说foo是一张地图.
bar = foo.clone()
Run Code Online (Sandbox Code Playgroud)
没有任何foo结构(例如,树)被复制.但是,从现在开始,bar它被视为副本,并且不允许任何更改传播回`foo'.
baz = bar[someKey]
baz.modifyInSomeWay()
Run Code Online (Sandbox Code Playgroud)
现在
baz.bar用新地图替换,保留新的baz(可能保留一些foo结构).foo 不受影响.但如果我们那么做......
baz.modifyAgain()
Run Code Online (Sandbox Code Playgroud)
... baz可以修改,因为我们有最新版本的.bar
不需要改变.
所有这些都需要持有的一些版本信息foo和bar关于增加它foo.clone(),并把它传递给baz某种方式(通过使代理对象?).
此外,已克隆的结构的任何部分都成为"历史的一部分",不能再被更改,这可以在运行时强制执行.
这有点类似于JavaScript的原型,但我更多的是因为它允许更改向上传播.我认为它会像版本控制系统.
以下代码可在 amd64 上的 Rust 1.8 上正常运行。
use std::mem;
fn main() {
let f: u8 = unsafe { mem::transmute(false) };
let t: u8 = unsafe { mem::transmute(true) };
assert_eq!(0, f);
assert_eq!(1, t);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,我可以假设这总是有效吗?我试图找到有关代表性的参考资料bool,但我只找到了this和this,但我认为这并不权威。
是否可以创建一个计算扩展项目数量的宏?
macro_rules! count {
($($name:ident),*) => {
pub enum Count {
$(
$name = 1 << $i // $i is the current expansion index
),*
}
}
}
count!(A, B, C);
Run Code Online (Sandbox Code Playgroud) 如果我有两个不同大小的数组:
let mut array1 = [0; 8];
let array2 = [1, 2, 3, 4];
Run Code Online (Sandbox Code Playgroud)
我将如何复制array2到前4个字节array1?我可以采用一个可变的4字节slice1,但我不确定如何或如果我可以分配它.
这些方法使用动态调度(接收特征对象&Debug作为参数):
这些方法使用静态分派,并根据相关entry方法编写:
为什么第一个方法列表使用动态分派而不是静态分派?如果使用静态调度,它们的使用会受到限制吗?