是否可以在 Rust 中返回一个包含可变数据引用的结构?

问题描述 投票:0回答:1

我正在制作一个小伪游戏,并想创建一个函数来返回通用敌人。由于某种原因,它不允许我使用

[0, 0]
。 这是代码:

struct Enemy<'a> {
    pos: &'a mut [i32; 2],// [0] = x, [1] = y
    veloc: &'a mut [i32; 2],// see `pos` property
    monstype: String,
    id: String
}

impl<'a> Enemy<'_> {
    pub fn new(monster_type: String) -> Enemy<'a> {
        Enemy {
            pos: &mut [0, 0],
            veloc: &mut [0, 0],
            monstype: monster_type,
            id: Enemy::generate_id(8)// unrelated, omitted from this code snippet
        }
    }
}

这会产生此错误:

error[E0515]: cannot return value referencing temporary value
  --> src\main.rs:19:9
   |
19 | /         Enemy {
20 | |             pos: &mut [0, 0],
21 | |             veloc: &mut [0, 0],
   | |                         ------ temporary value created here
22 | |             monstype: monster_type,
23 | |             id: Enemy::generate_id(8)
24 | |         }
   | |_________^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing temporary value
  --> src\main.rs:19:9
   |
19 | /         Enemy {
20 | |             pos: &mut [0, 0],
   | |                       ------ temporary value created here
21 | |             veloc: &mut [0, 0],
22 | |             monstype: monster_type,
23 | |             id: Enemy::generate_id(8)
24 | |         }
   | |_________^ returns a value referencing data owned by the current function

我在数组上尝试了

.clone()
,但这当然不起作用,因为数据仍然是临时的并且由函数拥有。

rust ownership
1个回答
0
投票

我想你可能正在寻找

struct Enemy {
    pos: [i32; 2],
    veloc: [i32; 2],
    monstype: String,
    id: String,
}

没有理由(至少,在您显示的代码片段中没有理由)

Enemy
借用任何东西,因此我们可以删除生命周期参数
'a
和所有借用复杂性,只返回数组。数组(至少是那些已知大小的数组)是完全有效的大小数据类型,并且可以作为结构的一部分返回。

如果您提前知道尺寸,您可以使用

Vec

struct Enemy {
    pos: Vec<i32>,
    veloc: Vec<i32>,
    monstype: String,
    id: String,
}

然后您可以使用永远有用的

vec
宏来构建这些。

Enemy {
  pos: vec![0, 0],
  veloc: vec![0, 0],
  monstype: String::from("Whatever"),
  id: String::from("0"),
}

最后,如果您的数组很大并且您有充分的理由担心按值传递它们,那么您可以使用

&mut
而非
Box
(用于借用)添加间接寻址。我建议这样做,除非你有充分的理由这样做。在大多数情况下,额外的间接寻址很可能会减慢程序的速度。但你可以

struct Enemy {
    pos: Box<[i32; 2]>,
    veloc: Box<[i32; 2]>,
    monstype: String,
    id: String,
}

然后构建为

Enemy {
  pos: Box::new([0, 0]),
  veloc: Box::new([0, 0]),
  monstype: String::from("Whatever"),
  id: String::from("0"),
}
© www.soinside.com 2019 - 2024. All rights reserved.