当我阅读关于泛型的 Rust 文档时,我发现了一个关于所有权的奇怪问题。看下面的片段:
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
let mut largest = number_list[0];
for number in number_list {
if number > largest {
largest = number;
}
}
println!("The largest number is {}", largest);
}
Run Code Online (Sandbox Code Playgroud)
为什么不largest取得向量第一个元素的所有权?我发现在前面关于向量的章节中,使用借用语法let largest = &v[0]将获得元素的所有权。为什么这段代码能通过编译器?
我有一个方法,我想返回一个元素的拥有副本。如果需要的话,我可以证明为什么我想要这个。
这是一个最小的可重现示例:(游乐场)
use std::collections::HashMap;
struct AsciiDisplayPixel {
value: char,
color: u32,
}
struct PieceToPixelMapper {
map: HashMap<usize, AsciiDisplayPixel>,
}
impl PieceToPixelMapper {
pub fn map(&self, index: usize) -> Option<AsciiDisplayPixel> {
let pixel = self.map.get(&index);
let pixel = match pixel {
None => return None,
Some(x) => x,
};
return Some(pixel.clone());
}
}
fn main() {
println!("Hello World");
}
Run Code Online (Sandbox Code Playgroud)
这无法编译
use std::collections::HashMap;
struct AsciiDisplayPixel {
value: char,
color: u32,
}
struct PieceToPixelMapper {
map: HashMap<usize, AsciiDisplayPixel>,
}
impl PieceToPixelMapper …Run Code Online (Sandbox Code Playgroud) 我有一个代表状态机的 Rust 枚举。我需要在状态之间移动一些数据(其中数据未实现Copy)。有什么好的使用方法?
基本上,我想消除bravo.clone()此代码中的调用。当原始数据将被删除时,必须克隆该数据是令人失望的。我宁愿做的事情是沿着bravo: *bravo\xe2\x80\x94 的路线将旧值移出bravo和State1移入State2. 但我不能直接这样做,因为这会暂时使self.statewhile Construction的值无效State2。
enum MyStateMachine {\n Idle,\n State1 {\n alpha: usize,\n bravo: String,\n },\n // State2 is a superset of State1\n State2 {\n alpha: usize,\n bravo: String,\n charlie: usize,\n },\n}\n\nimpl MyStateMachine {\n fn to_state2(&mut self, charlie: usize) -> Result<(), String> {\n use MyStateMachine::*;\n\n match self {\n State1 { alpha, bravo } => {\n *self = State2 {\n …Run Code Online (Sandbox Code Playgroud) 我正在浏览Rust 官方网站上的Rust 书籍,并发现了以下段落:
\n\n\n请注意,我们需要使其
\nv1_iter可变:在迭代器上调用 next 方法会更改迭代器用于跟踪其在序列中位置的内部状态。换句话说,此代码消耗或用完迭代器。每次调用 next 都会消耗迭代器中的一个项目。当我们使用 for 循环时,\xe2\x80\x99 不需要使其可变,因为循环在幕后v1_iter获取了所有权并使其可变。v1_iter
如果您注意到最后一行。它说 for 循环使可变变量在幕后变得不可变。如果可以的话,那么作为程序员的我们是否也可以做同样的事情呢?
\n就像我知道这不安全,我们不应该这样做,但只是想知道这是否可能。
\n我试图一次对多个字符串块执行并行操作,并且发现借用检查器存在问题:
(对于上下文,identifiers是Vec<String>来自 CSV 文件的,client是 reqwest,target是Arc<String>一次写入多次读取的)
use futures::{stream, StreamExt};
use std::sync::Arc;
async fn nop(
person_ids: &[String],
target: &str,
url: &str,
) -> String {
let noop = format!("{} {}", target, url);
let noop2 = person_ids.iter().for_each(|f| {f.as_str();});
"Some text".into()
}
#[tokio::main]
async fn main() {
let target = Arc::new(String::from("sometext"));
let url = "http://example.com";
let identifiers = vec!["foo".into(), "bar".into(), "baz".into(), "qux".into(), "quux".into(), "quuz".into(), "corge".into(), "grault".into(), "garply".into(), "waldo".into(), "fred".into(), "plugh".into(), "xyzzy".into()];
let id_sets: Vec<&[String]> …Run Code Online (Sandbox Code Playgroud) 我尝试从一个小时开始编写代码示例,在String. 因此,主函数借用了一个字符串给一个添加空格的函数,然后,我想将字符串返回到主函数中。
fn main() {
...
let mut line = String::new();
line = make_spaces(5, &mut line);
}
fn make_spaces(number: u8, string: &mut String) -> &mut String {
for _ in 0..number {
string.push(' ');
}
string
}
Run Code Online (Sandbox Code Playgroud)
但借用检查器给我以下错误:
error[E0308]: mismatched types
--> src/main.rs:14:12
|
14 | line = make_spaces(left_spaces, &mut line);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected struct `String`, found `&mut String`
| help: try using a conversion method: `make_spaces(left_spaces, &mut line).to_string()`
Run Code Online (Sandbox Code Playgroud)
我是新手rust,我知道我不懂借钱。但我上网查了一下,还是不太明白。
据我了解,我将line所有权赋予 …
是否可以构建结构
struct MyFn<A, B> {
call: fn(A) -> B
}
Run Code Online (Sandbox Code Playgroud)
这样它就能够捕获不可变的变量,如下面的代码片段所示?
let y: &f64 = &3.0
let my_fn: MyFn<f64, f64> {
call: |x| {
x + *y
}
}
Run Code Online (Sandbox Code Playgroud)
我知道在这种情况下需要闭包,但是 的类型应该是什么,call以便它可以捕获任何不可变的引用(例如函数引用)?
我正在尝试更详细地了解 Rust 的所有权和生命周期,但我对这段代码感到非常困惑:
let mut lst = vec![1, 2, 3];
let mut x = &mut 0;
for value in &mut lst {
*value += 1;
*x += 1;
x = value;
}
*x += 1;
println!("{:?}", &lst);
Run Code Online (Sandbox Code Playgroud)
据我了解,Rust 不允许对任何值有多个可变引用,并且对向量中元素的可变引用也会借用向量本身。因此,不可能同时对向量中的两个元素进行可变引用。
但在上面的代码中,循环体存储了对循环外部lst元素的可变引用。x然后,在下一次迭代中,它需要另一个对 中不同元素的可变引用lst,同时为我提供对列表中两个元素的两个可变引用。
所以我的问题是:为什么允许这样做?
我有这个工作代码:
let foo_ips = vec![Ipv4Addr::new(127,0,0,1),
Ipv4Addr::new(127,0,0,2),
Ipv4Addr::new(127,0,0,3)];
let foos: Vec<Foo> = foo_ips.iter().map(|x| {Foo::new(*x)}).collect();
Run Code Online (Sandbox Code Playgroud)
我相信这是使用复制构造函数来创建 newIpv4Addr来传递给Foo::new().
我对么?
如果是这样,我如何取出ipsfoo_ips 将每个的所有权传递给Foo::new()?
我的失败代码(最小的、可重现的示例):
// my code
fn test() {
let mut list: Vec<Text> = Vec::new();
const ARRAY: [char; 3] = ['a', 'b', 'c'];
for (i, _) in ARRAY.iter().enumerate() {
list.push(Text::new(&ARRAY[i].to_string()));
}
}
// external crate
#[derive(Debug, Clone, Copy, PartialEq)]
struct Text<'a> {
pub text: &'a str,
}
impl<'a> Text<'a> {
pub fn new(text: &'a str) -> Self {
Text {
text
}
}
}
Run Code Online (Sandbox Code Playgroud)
编译器:“借用时临时值下降”。下面有红色波浪线
ARRAY[i].to_string()
Run Code Online (Sandbox Code Playgroud)
我猜是经典的借用检查器问题?
我尝试将类型更改为&strs 而不是chars,一切正常:
// my code
fn test() {
let …Run Code Online (Sandbox Code Playgroud)