在 Rust 中是否可以通过让它们指向彼此的内存表示来交换 2 个向量(不隐藏先前的变量)?
我正在从 C 移植一些代码,这在处理指针时非常简单。
伪代码(类 C):
float *a = malloc(size);
float *b = malloc(size);
error = calc_params(curve, a);
for (i = 0; i < REFINE_ITER_MAX; i++) {
/* reads 'a', refines to 'b' */
calc_params_refine(curve, a, b);
error_test = calc_params(curve, a);
if (error_test < error) {
/* How to do this in Rust??? */
float *swap = a;
a = b;
b = swap;
}
else {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码使用每一步都交换的源/目标数组将一个数组细化为另一个数组。
给定两个长度相同并使用原始类型(float/ i32/ …
鉴于宏匹配示例,这显示了宏如何匹配参数。
我在这里做了非常小的改动来使用数字:
macro_rules! foo {
(0 => $e:expr) => (println!("mode X: {}", $e));
(1 => $e:expr) => (println!("mode Y: {}", $e));
}
fn main() {
foo!(1 => 3);
}
Run Code Online (Sandbox Code Playgroud)
作品、印刷: mode Y: 3
但是我想使用一个常量作为参数,这可以起作用吗:
const CONST: usize = 1;
macro_rules! foo {
(0 => $e:expr) => (println!("mode X: {}", $e));
(1 => $e:expr) => (println!("mode Y: {}", $e));
}
fn main() {
foo!(CONST => 3);
}
Run Code Online (Sandbox Code Playgroud)
这在 Rust 中可能吗?
请注意,使用常规match语句对我来说不可用,因为在我的代码中,每个分支都解析为不同的类型,从而产生错误。所以我特别想知道是否可以将常量传递给宏。
在C中,在单个表达式中分配和比较是很常见的:
n = n_init;
do {
func(n);
} while ((n = n.next) != n_init);
Run Code Online (Sandbox Code Playgroud)
据我了解,这可以用Rust表示:
n = n_init;
loop {
func(n);
n = n.next;
if n == n_init {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
其作用与C版本相同(假设循环体不使用continue).
是否有更简洁的方式在Rust中表达这个,或者上面的例子是理想的?
出于这个问题的目的,假设所有权或满足借用检查器不是问题.由开发人员来满足这些要求.
例如,作为整数:
n = n_init;
loop {
func(&vec[n]);
n = vec[n].next;
if n == n_init {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来很明显,Rust的例子是惯用的Rust - 但是我希望将这种循环风格转移到Rust,我很想知道是否有更好/不同的表达方式.
Markdown如何与rustdoc一起使用以包含图表或ASCII艺术?
通过阅读手册,三重反向标记可用于代码片段.如何包含文字的非格式化文本?
(像Doxygen的 东西<pre>...</pre>)
既然可以传递对向量的可变引用(不会导致移动),那么如何将 anOption<reference>多次传递给函数而不导致借用检查错误呢?
Option<&mut Vec<usize>>这个简单的示例仅显示了将 an 多次传递给函数时会发生什么:
fn maybe_push(mut v_option: Option<&mut Vec<usize>>) -> usize {
let mut c = 0;
if let Some(ref mut v) = v_option.as_mut() {
for i in 0..10 {
v.push(i);
c += i;
}
}
return c;
}
fn maybe_push_multi(v_option: Option<&mut Vec<usize>>) -> usize {
let mut c = 0;
c += maybe_push(v_option);
c += maybe_push(v_option);
c += maybe_push(None);
return c;
}
fn main() {
let mut v: Vec<usize> = vec![];
let v_option = …Run Code Online (Sandbox Code Playgroud) 我想创建自己的vector struct,以便可以附加其他方法。
pub struct MyStructVec(pub Vec<MyStruct>);
Run Code Online (Sandbox Code Playgroud)
完成此操作后,将如何创建此向量的新实例?
MyStructVec::new()无法识别。现有的矢量创建方法将如何与这种类型一起使用?(new,with_capacity...等)
当可变参数作为函数参数传递时,借用检查器不允许将其用于构造其他参数,即使这些参数克隆值而不持有引用也是如此。
虽然在函数外部分配变量始终是一个选项1,但从逻辑上讲,这似乎过于热心,借用检查器可以考虑这一点。
这是按预期工作还是应该解决?
#[derive(Debug)]
struct SomeTest {
pub some_value: f64,
pub some_other: i64,
}
fn some_fn(var: &mut SomeTest, other: i64) {
println!("{:?}, {}", var, other);
}
fn main() {
let mut v = SomeTest { some_value: 1.0, some_other: 2 };
some_fn(&mut v, v.some_other + 1);
// However this works!
/*
{
let x = v.some_other + 1;
some_fn(&mut v, x);
}
*/
}
Run Code Online (Sandbox Code Playgroud)
给出这个错误:
#[derive(Debug)]
struct SomeTest {
pub some_value: f64,
pub some_other: i64,
}
fn some_fn(var: &mut …Run Code Online (Sandbox Code Playgroud) 移动API使用时Cow<[sometype]>,必须更换:
some_func(arg1, arg2, arg3);
Run Code Online (Sandbox Code Playgroud)
附:
some_func(Cow::from(&arg1[..]), Cow::from(&arg2[..]), Cow::from(&arg3[..]));
Run Code Online (Sandbox Code Playgroud)
语法相当密集.
Cow当作为函数参数传递时,是否有一种方法可以将向量或切片强制转换为它们的等价物?
可能有充分的理由不这样做,例如,如果您多次对函数使用相同的参数,则显式语法是提示Cow<[]>应该为版本分配变量并保留.但是,我很想知道这是否可行.
给定多个相似的结构,实现匹配签名的函数可能是有用的.
下面的简单示例可以很好地工作,但不能确保所有函数都遵循相同的函数签名.
impl FooStruct {
pub fn calc_value(seed: i64) -> i64 { /* function body! */ }
}
impl BarStruct {
pub fn calc_value(seed: i64) -> i64 { /* function body! */ }
}
Run Code Online (Sandbox Code Playgroud)
使用特征解决了这个问题:
pub trait CanCalcValue {
fn calc_value(seed: i64) -> i64;
}
impl CanCalcValue for FooStruct {
fn calc_value(seed: i64) -> i64 { /* function body! */ }
}
impl CanCalcValue for BarStruct {
fn calc_value(seed: i64) -> i64 { /* function body! */ }
}
Run Code Online (Sandbox Code Playgroud)
但是,现在我必须添加 …
使用切片语法访问切片很简单: slice = vector[i..j]
但是,在存储范围的情况下,我可以告诉您不能这样做:
struct StructWithRange {
range: std::ops::Range<usize>,
}
fn test_slice(s: &StructWithRange, vector: &Vec<i32>) {
let slice = &vector[s.range];
println!("{:?}", slice); // prints [2, 3]
}
fn main() {
let vector = vec![1,2,3,4,5];
let s = StructWithRange {
range: 1..3
};
test_slice(&s, &vector);
}
Run Code Online (Sandbox Code Playgroud)
这给出了错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:6:25
|
6 | let slice = &vector[s.range];
| ^ cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)
有没有办法从范围中获取切片而不扩展它?
例如:vector[s.range.start..s.range.end]
如果usize结构中的a可以用于索引查找,为什么不能以Range<usize>相同的方式使用它?