我没有锈的别名规则特别深刻的理解(从我听说他们没有扎实的定义),但我无法理解是什么使这个代码示例中std::slice
文档还好.我在这里重复一遍:
let x = &mut [1, 2, 4];
let x_ptr = x.as_mut_ptr();
unsafe {
for i in 0..x.len() {
*x_ptr.offset(i as isize) += 2;
}
}
assert_eq!(x, &[3, 4, 6]);
Run Code Online (Sandbox Code Playgroud)
我在这里看到的问题是x
,作为&mut
参考,可以假设编译器是唯一的.x
get 的内容经过修改x_ptr
,然后通过回读x
,我认为没有理由为什么编译器不能假设x
没有被修改,因为它从未通过唯一的现有&mut
引用进行修改.
那么,我在这里错过了什么?
编译器是否需要假设*mut T
可能是别名&mut T
,即使通常允许它假设&mut T
永远不会别名别名&mut T
?
该unsafe
块是否充当某种别名障碍,编译器假定其中的代码可能已修改了范围内的任何内容?
此代码示例是否已损坏?
如果有某种稳定的规则使这个例子没问题,究竟是什么呢?它的范围是多少?我应该担心多少假设破坏unsafe
Rust代码中的随机事物?
由于使用了相关类型,我在Rust 1.14中遇到了一生的错误,由以下两个类似的程序演示,第一个编译没有错误,第二个编译有生命周期错误.
程序#1 - 编译没有错误
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a ()>;
}
struct Alpha<'a, T: Trait<'a>> {
_dummy: std::marker::PhantomData<(&'a (), T)>,
}
fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {}
fn main() {
for x in Vec::<Alpha<Impl>>::new().into_iter() {
use_alpha(&x); // <-- ok
}
}
Run Code Online (Sandbox Code Playgroud)
程序#2 - 有生命周期错误
trait Trait<'a> {
type T;
}
struct Impl;
impl<'a> Trait<'a> for Impl {
type T = std::marker::PhantomData<&'a ()>;
}
struct Alpha<'a, T: Trait<'a>> …
Run Code Online (Sandbox Code Playgroud) 我有一个结构Foo
:
struct Foo {
v: String,
// Other data not important for the question
}
Run Code Online (Sandbox Code Playgroud)
我想处理数据流并将结果保存到字段中Vec<Foo>
,Vec<Foo>
并在字段上为此创建索引Foo::v
.
我想使用a HashMap<&str, usize>
作为索引,其中键将是&Foo::v
,而值是该位置Vec<Foo>
,但我对其他建议持开放态度.
我想尽可能快地处理数据流,这需要两次不做明显的事情.
例如,我想:
String
每个数据流读取只分配一次Rc
或增加运行时间RefCell
.借用检查器不允许此代码:
let mut l = Vec::<Foo>::new();
{
let mut hash = HashMap::<&str, usize>::new();
//here is loop in real code, like:
//let mut s: String;
//while get_s(&mut s) {
let s = "aaa".to_string();
let idx: usize = match hash.entry(&s) …
Run Code Online (Sandbox Code Playgroud) 我有两个类型的变量&T
,x
并且y
我在函数内部交换:
pub fn foo<T: Copy>(mut x: &T) {
let y_owned = *x;
let mut y = &y_owned;
for _ in 0..10 {
do_work(x, y);
std::mem::swap(&mut x, &mut y);
}
}
fn do_work<T>(_x: &T, _y: &T) {}
Run Code Online (Sandbox Code Playgroud)
此代码无法编译,给出以下错误:
error[E0597]: `y_owned` does not live long enough
--> src/lib.rs:3:22
|
3 | let mut y = &y_owned;
| ^^^^^^^ borrowed value does not live long enough
...
8 | }
| - borrowed value only lives until …
Run Code Online (Sandbox Code Playgroud) 我正在尝试解析文件并Vec<Vec<&str>>
从函数返回。但在推送到向量时,我在文件读取循环内遇到借用值错误。
use std::io::{self, BufReader, prelude::*};
use std::fs::File;
fn read() -> Vec<Vec<&'static str>> {
let file = File::open("~/test").expect("failed to read file");
let reader = BufReader::new(file);
let mut main_vector: Vec<Vec<&str>> = Vec::new();
for line in reader.lines() {
match line {
Ok(v) => {
let mut sub_vector: Vec<&str> = Vec::new();
for element in v.split_whitespace().collect::<Vec<&str>>() {
sub_vector.push(element);
}
main_vector.push(sub_vector);
},
Err(e) => panic!("failed to parse: {:?}", e),
}
}
//return main_vector;
}
Run Code Online (Sandbox Code Playgroud)
这是编译器错误:
error[E0597]: `v` does not live long enough
--> src/main.rs:67:32 …
Run Code Online (Sandbox Code Playgroud) 我有以下 Rust 程序。
fn main() {
let v = vec![100, 32, 57];
for i in v {
println!("{}", i);
}
println!("{:?}", v);
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我得到:
fn main() {
let v = vec![100, 32, 57];
for i in v {
println!("{}", i);
}
println!("{:?}", v);
}
Run Code Online (Sandbox Code Playgroud)
该错误指出在 处发生了移动for i in v
。但我只是使用v
由let v = vec![100, 32, 57]
. 它不是像 那样的东西let v2 = v; for i in v2 ...
,它将值从v
移到v2
。谁能帮忙解释一下?
我正在尝试将 a 转换HashSet<String>
为一个排序向量,然后可以join
用逗号进行编辑:
use std::collections::HashSet;
fn main() {
let mut hs = HashSet::<String>::new();
hs.insert(String::from("fee"));
hs.insert(String::from("fie"));
hs.insert(String::from("foo"));
hs.insert(String::from("fum"));
let mut v: Vec<&String> = hs.iter().collect();
v.sort();
println!("{}", v.join(", "));
}
Run Code Online (Sandbox Code Playgroud)
这不会编译:
use std::collections::HashSet;
fn main() {
let mut hs = HashSet::<String>::new();
hs.insert(String::from("fee"));
hs.insert(String::from("fie"));
hs.insert(String::from("foo"));
hs.insert(String::from("fum"));
let mut v: Vec<&String> = hs.iter().collect();
v.sort();
println!("{}", v.join(", "));
}
Run Code Online (Sandbox Code Playgroud)
我明白为什么我不能加入Vec<&String>
,但我怎样才能将 转换HashSet
为 a Vec<String>
,以便它可以加入?
在 Rust 中打印由空格分隔的迭代器的惯用方法是什么?似乎并不适用,因为迭代器Args
返回String
值,不像迭代器HashSet
返回&String …
fn main() {
let strA = "a";
let result;
{
let strB = "abc";
result = longest(strA, strB); // Will return strB
}
println!("The longest string is {}", result); // result now point to strB!!
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
Run Code Online (Sandbox Code Playgroud)
'a
将得到的混凝土的寿命等于该较小的寿命的x
和y
那么为什么strB
现在在其范围之外可见?
这是该str
类型的使用方式:
let hello = "Hello, world!";
// with an explicit type annotation
let hello: &'static str = "Hello, world!";
Run Code Online (Sandbox Code Playgroud)
let hello: str = "Hello, world!";
造成 expected `str`, found `&str`
为什么文本的默认类型str
与所有原始类型、向量和String
? 为什么是参考?