我有一个在堆栈上分配向量的函数.此代码不起作用:
fn my_func(n: i32) {
let mut v = Vec::with_capacity(n);
}
Run Code Online (Sandbox Code Playgroud)
编译器说n需要成为一个usize.我认为从类型安全的角度来看,这是有道理的,但我需要n在其他需要i32调用的计算中使用.处理这个问题的正确方法是什么?
我正在尝试遍历一个字符串,但迭代在n每个字符的长度切片而不是迭代器.以下代码手动完成此操作,但有更实用的方法吗?
fn main() {
let string = "AAABBBCCC";
let offset = 3;
for (i, _) in string.chars().enumerate() {
if i % offset == 0 {
println!("{}", &string[i..(i+offset)]);
}
}
}
Run Code Online (Sandbox Code Playgroud) 这是我的问题的一个相当简单的再现:
fn str_to_u8(s: &str) -> &[u8] {
let vector = s.chars().map(|c| c as u8).collect::<Vec<u8>>();
let slice = vector.as_slice();
slice
}
Run Code Online (Sandbox Code Playgroud)
编译器说它的vector寿命不够长,这是有道理的。有没有办法强制vector“移动”到slice,以便当调用者获得切片的所有权时,它也获得切片的所有权vector?
我正在研究一种涉及Beetle存储在一个对象中的一堆对象的游戏HashMap.每个甲虫都有一个位置,它也可以有一个目标id,它是哈希中另一个甲虫的关键.如果甲虫有目标,则每次游戏循环执行时都需要移动到目标.
我无法执行目标当前位置的查找,因为您不能同时拥有可变且不可变的借位.我明白了,但任何想法如何重组我的具体案例?
我想我只是陷入了几乎任何其他语言的容易程度,我无法看到惯用的Rust方式来做到这一点.这是一个非常小但完整的例子:
use std::collections::HashMap;
type Beetles = HashMap<i32, Beetle>;
struct Beetle {
x: f32,
y: f32,
target_id: i32,
}
impl Beetle {
fn new() -> Beetle {
Beetle {
x: 0.0,
y: 0.0,
target_id: -1,
}
}
}
fn main() {
let mut beetles: Beetles = HashMap::new();
beetles.insert(0, Beetle::new());
beetles.insert(1, Beetle::new());
set_target(&mut beetles, 0, 1);
move_toward_target(&mut beetles, 0);
}
fn set_target(beetles: &mut Beetles, subject_id: i32, target_id: i32) {
if let Some(subject) = beetles.get_mut(&subject_id) {
subject.target_id …Run Code Online (Sandbox Code Playgroud) 我正在使用一个用于多态的枚举,类似于以下内容:
enum MyType {
Variant1 { a: i32, b: i32 },
Variant2 { a: bool, b: bool },
}
Run Code Online (Sandbox Code Playgroud)
是否有干净的方法将现有结构用于Variant1和Variant2?我已经完成以下工作:
struct Variant1 {
a: i32,
b: i32,
}
struct Variant2 {
a: bool,
b: bool,
}
enum MyType {
Variant1(Variant1),
Variant2(Variant2),
}
Run Code Online (Sandbox Code Playgroud)
但是感觉很笨重。我想知道是否有更好的方法来完成类似的事情。
在编写相对实时的代码时,通常避免主执行循环中的堆分配.因此,根据我的经验,您可以在初始化步骤中分配程序所需的所有内存,然后根据需要传递内存.C中的玩具示例可能如下所示:
#include <stdlib.h>
#define LEN 100
void not_realtime() {
int *v = malloc(LEN*sizeof(int));
for (int i=0; i<LEN; i++) {
v[i] = 1;
}
free(v);
}
void realtime(int *v, int len) {
for (int i=0; i<len; i++) {
v[i] = 1;
}
}
int main(int argc, char **argv) {
not_realtime();
int *v = malloc(LEN*sizeof(int));
realtime(v, LEN);
free(v);
}
Run Code Online (Sandbox Code Playgroud)
而且我相信Rust中的等价物:
fn possibly_realtime() {
let mut v = vec![0; 100];
for i in 0..v.len() {
v[i] = 1;
}
}
fn realtime(v: &mut …Run Code Online (Sandbox Code Playgroud) 什么是在Rust中逐个元素地比较2个向量或字符串的最佳方法,同时能够对每对元素进行处理?例如,如果您想要计算不同元素的数量.这就是我正在使用的:
let mut diff_count: i32 = 0i32;
for (x, y) in a.chars().zip(b.chars()) {
if x != y {
diff_count += 1i32;
}
}
Run Code Online (Sandbox Code Playgroud)
这是正确的方式还是有更规范的东西?
我正在尝试创建一个简单的宏,vec!无论它接收到什么都会调用,然后在返回新向量之前执行一些简单的处理:
macro_rules! sorted_vec {
($x:expr) => {
{
let v = vec![$x];
v.sort();
v
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我的宏试图解析语法,所以它抱怨逗号等等.这是有道理的,但我不知道如何解决它.我认为不是expr正确的片段说明符.如何在vec!不进行处理的情况下将原始输入传递给它?
我有一个结构向量,我将向量中的每个元素与其他每个元素进行比较,并在某些情况下改变当前元素.
我的问题是你不能同时发生可变和不可变的借位,但是我不知道如何重新解决我的问题以解决这个问题而不克隆当前元素或整个向量,这看起来像因为我只是在改变当前元素,所以不需要与自身进行比较(我跳过这种情况).
我确信在Rust中有一种惯用的方法.
struct MyStruct {
a: i32,
}
fn main() {
let mut v = vec![MyStruct { a: 1 }, MyStruct { a: 2 }, MyStruct { a: 3 }];
for elem in v.iter_mut() {
for other_elem in v.iter() {
if other_elem.a > elem.a {
elem.a += 1;
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用特征来实现类似模板方法模式的东西.在算法执行的部分过程中,我希望它能够调用回调来报告其进度.我一直试图完成这项工作的方法是Fn()在我的结构上存储一个实现特征的结构,然后提供一个get_callback方法来为特征上的默认方法提供回调.不幸的是它不起作用.
我怀疑解决方案将涉及将回调放入a Box并可能返回引用的某种组合,但我无法使其工作.这是一个最小的非工作示例:
trait MyTrait<T: Fn()> {
fn default(&self) {
let cb = self.get_callback();
cb();
}
fn get_callback(&self) -> T;
}
struct MyStruct<T: Fn()> {
callback: T,
}
impl<T: Fn()> MyTrait<T> for MyStruct<T> {
fn get_callback(&self) -> T {
self.callback
}
}
fn main() {
let x = MyStruct { callback: || {} };
x.default();
}
Run Code Online (Sandbox Code Playgroud)
error[E0507]: cannot move out of borrowed content
--> src/main.rs:16:9
|
16 | self.callback
| ^^^^ cannot move …Run Code Online (Sandbox Code Playgroud)