在尝试实现一个迭代器,它为链表的元素产生可变引用时,我偶然发现了一个奇怪的问题.
这很好用:
impl<'a, T> Iterator<&'a T> for LinkedListIterator<'a, T>{
fn next(&mut self) -> Option<&'a T> {
match self.current {
&Cell(ref x, ref xs) => {self.current = &**xs; Some(x)},
&End => None
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用; 编译器说生命周期self太短,无法保证其内容可以安全地重新借用:
impl<'a, T> Iterator<&'a mut T> for LinkedListMutIterator<'a, T>{
fn next(&mut self) -> Option<&'a mut T> {
match self.current {
&Cell(ref mut x, ref mut xs) => {self.current = &mut **xs; Some(x)},
&End => None
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这两个例子都可以工作,或者两者都没有,但是我无法理解借用可变和不可变的东西会影响编译器检查生命周期的方式.当然,如果有足够长的东西可以安全借用,它的寿命足够长,可以安全地可靠地借用?
编辑:这是两个迭代器的定义:
pub struct LinkedListIterator<'a, …Run Code Online (Sandbox Code Playgroud) 我想在F#中做一个循环图
我的节点类型看起来像这样:
type Node = { Value : int; Edges : Node list }
Run Code Online (Sandbox Code Playgroud)
我的问题是:为了有周期,我是否需要让Edges可变?
虽然我理解为什么a var不能覆盖valin子类,反之亦然,但我无法理解为什么Scala不允许defin子类覆盖var超类中的
class Car {
var age = 32
}
class SedanCar extends Car {
override def age = 54
}
Run Code Online (Sandbox Code Playgroud)
因为var可变,为什么不允许a def覆盖呢?有人可以帮我理解这个吗?
scala liskov-substitution-principle immutability mutability uap
我有一个 Swift 函数,它返回两个值的元组。第一个值通常(但并非总是)用作调用者中一段可变状态的“更新”版本(我知道我也可以使用inout它而不是元组,但这使得它更烦人保留旧状态的同时保留新状态)。第二个值是函数生成的通常不可变的返回值,其无意覆盖任何现有的可变状态。
从概念上讲,用法如下:
var state = // initialize
(state, retval1) = process(state)
(state, retval2) = process(state)
(state, retval3) = process(state)
Run Code Online (Sandbox Code Playgroud)
显然,这里的问题是retval1、retval2、 和retval3从未被声明,编译器会生气。
state必须是 avar并且不能重新声明,所以我不能写
let (state, retval) = process(state)
Run Code Online (Sandbox Code Playgroud)
但是,retval永远不会被修改,并且应该let作为最佳实践和良好编码风格的问题来声明。
我希望以下语法可能有效,但事实并非如此:
(state, let retval) = process(state)
Run Code Online (Sandbox Code Playgroud)
我应该如何解压/解构这个元组?
我有一个Vec<&str>,我想删除所有元素的前缀.这是我隐约想要的:
fn remove_prefix(v: &mut [&str], prefix: &str) {
for t in v.iter_mut() {
t = t.trim_left_matches(prefix);
}
}
Run Code Online (Sandbox Code Playgroud)
但是我似乎无法将所有的东西都mut放在正确的位置.或者这可能与生命有关?任何人都可以给我一个提示吗?这是我当前的错误:
makefile_to_qbs.rs:22:7: 22:34 error: mismatched types:
expected `&mut &str`,
found `&str`
(values differ in mutability) [E0308]
makefile_to_qbs.rs:22 t = t.trim_left_matches(prefix);
Run Code Online (Sandbox Code Playgroud) 如果我猜对了std::rc::Rc,就不可能在 Rust 中通过a创建可变借用,您必须使用Cell或RefCell。但无论如何我无法理解如何使用它们。例如考虑这个简单的例子:
use std::cell::RefCell;
struct X (i32);
impl X {
fn foo(&mut self) {
self.0 = 0;
}
}
fn main () {
let x = X(5);
let rcx = RefCell::new(&x);
let mut mutx: std::cell::RefMut<&X> = rcx.borrow_mut();
(*mutx).foo();
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
16:5: 16:9 error: cannot borrow immutable local variable `mutx` as mutable
16 mutx.foo();
Run Code Online (Sandbox Code Playgroud)
但是,如果我从行中删除引用(并更新类型mutx):
let rcx = RefCell::new(x);
Run Code Online (Sandbox Code Playgroud)
一切安好。但我不明白为什么,因为RefMut::deref_mut() -> &mut T在第 16 …
我正在通过显式注释函数签名来测试我对 Rust 生命周期的理解,并且我创建了一个我不确定我是否理解的示例。
在这个例子中,我模拟了共享一本书并在其中翻页的概念。为此,我使用了一个可变引用,我将其传递给一个borrow_and_read更新结构curr_page字段的Book函数。我的Book结构和main函数看起来像:
#[derive(Debug)]
pub struct Book<'a> {
pub title: &'a str,
pub curr_page: Option<i32>,
pub page_count: i32,
}
fn borrow_and_read<'a>(a_book: &'a mut Book<'a>) {
match a_book.curr_page {
Some(page) => a_book.curr_page = Some(page + 1),
None => a_book.curr_page = Some(0),
};
}
fn main() {
let mut the_book: Book = Book {
title: "The Book",
curr_page: None,
page_count: 104,
};
let a_book: &mut Book = &mut the_book;
borrow_and_read(a_book);
borrow_and_read(a_book); …Run Code Online (Sandbox Code Playgroud) 如果这很简单,请道歉。我正在学习 rust 并习惯奇怪的借用系统。通常,您只需更改方法调用的语法即可获得所需的行为,但是,在这种情况下,现在似乎有办法了。
我的代码的简化版本是这样的:EventPumpif from SDL。
struct Example {
pump: EventPump
}
impl Example {
fn method(&mut self) {
for event in pump.poll_iter() {
self.other_method();
}
}
fn other_method(&self) {
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到以下错误:
error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
--> src\game.rs:53:67
|
30 | for event in self.pump.poll_iter();
| ---------------------
| |
| mutable borrow occurs here
| mutable borrow later used here
...
53 | self.other_method();
| ^^^^ immutable borrow …Run Code Online (Sandbox Code Playgroud) 我知道 Rust 引用很像 C 指针,并且我一直将 Rust 引用视为 C 指针。经过一些实验和搜索,我很困惑。
\n我熟悉 C,并且读过What\'s the Difference between Placeing \xe2\x80\x9cmut\xe2\x80\x9d before a variable name and after the \xe2\x80\x9c:\xe2\ x80\x9d?,给出下表:
\n\n\n …Run Code Online (Sandbox Code Playgroud)\n// Rust C/C++\n a: &T == const T* const a; // can\'t mutate either\nmut a: &T == const T* a; // can\'t mutate what is pointed to\n a: &mut T == T* const a; // can\'t mutate pointer\nmut a: &mut T == T* a; // can mutate both\n
我时不时地会遇到在循环内借用(或不借用)可变变量的相同问题,最后我坐下来编译了一个最小的示例。因此,代码有点愚蠢,但这是我能想到的最短版本,突出了问题:
\nstruct Association {\n used: bool,\n key: usize,\n value: String,\n}\n\nimpl Association {\n fn new(key: usize, value: &str) -> Self {\n Association{used: false, key: key, value: value.to_string()}\n }\n}\n\nfn find_unused<\'a>(data: &\'a mut Vec<Association>) -> Option<&\'a String> {\n for k in 0.. {\n for a in data {\n if a.key == k && !a.used {\n a.used = true;\n return Some(&a.value);\n }\n }\n }\n None\n}\n\nfn main() {\n let mut assoc = vec![\n Association::new(7, "Hello"),\n Association::new(9, "World")\n ];\n\n println!("{}", find_unused(&mut assoc).unwrap());\n println!("{}", find_unused(&mut assoc).unwrap());\n}\n …Run Code Online (Sandbox Code Playgroud) mutability ×10
rust ×7
immutability ×3
reference ×3
lifetime ×2
borrowing ×1
coding-style ×1
f# ×1
graph ×1
iterator ×1
liskov-substitution-principle ×1
scala ×1
swift ×1
tuples ×1
uap ×1