由于与代码组织相关的原因,我需要编译器接受以下(简化)代码:
fn f() {
let mut vec = Vec::new();
let a = 0;
vec.push(&a);
let b = 0;
vec.push(&b);
// Use `vec`
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨
error: `a` does not live long enough
--> src/main.rs:8:1
|
4 | vec.push(&a);
| - borrow occurs here
...
8 | }
| ^ `a` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error: `b` does not live long enough
--> src/main.rs:8:1
| …Run Code Online (Sandbox Code Playgroud) 我遇到了这个问题format!,据我所知,在一个没有锚定到任何东西的模式中创建一个临时值。
let x = 42;
let category = match x {
0...9 => "Between 0 and 9",
number @ 10 => format!("It's a {}!", number).as_str(),
_ if x < 0 => "Negative",
_ => "Something else",
};
println!("{}", category);
Run Code Online (Sandbox Code Playgroud)
在这段代码中, 的类型category是 a &str,它通过返回一个像 的文字来满足"Between 0 and 9"。如果我想使用 将匹配的值格式化为切片as_str(),则会出现错误:
let x = 42;
let category = match x {
0...9 => "Between 0 and 9",
number @ 10 => format!("It's a {}!", …Run Code Online (Sandbox Code Playgroud) 我试图理解 Rust 多态性。从我的 OOP 背景来看,我希望以下 Rust 代码能够工作:
use std::io::{stdin, Read};
fn main() {
let r: Read = stdin();
println!("ok");
}
Run Code Online (Sandbox Code Playgroud)
但它没有:
use std::io::{stdin, Read};
fn main() {
let r: Read = stdin();
println!("ok");
}
Run Code Online (Sandbox Code Playgroud)
我知道有一个Readimpl for StdIn,那么我怎样才能使这个(或任何正确的方法来做到这一点)工作,即。use Stdin,或 a File,或什至是 aString如果可能(无法找到实现)在Read预期a 的地方使用?
我不认为我可以在这里使用泛型,因为我需要将 的实例(r可以是任何实现的Read)传递给另一个方法,但如果我错了,请告诉我。
在搜索有关保守impl trait的文档时,我发现了这个例子:
struct A {
x: [(u32, u32); 10]
}
impl A {
fn iter_values<'a>(&'a self) -> impl 'a + Iterator<Item = u32> {
self.x.iter().map(|a| a.0)
}
}
Run Code Online (Sandbox Code Playgroud)
生命周期'a在返回类型中意味着什么?
我知道关于终身受限Box的这个问题,但我认为用例是不同的.如果我理解答案:
特质对象仅对生命周期'a有效
这意味着生活在堆中某处的特征对象将在一生中持续'a.
但在这里,这不是一个特质对象,而是一个生活在堆栈中的具体对象.因此编译器不需要提供有关其生命周期的提示.
我对此缺少什么?
我有一个结构,主要封装了一个向量:
struct Group<S> {
elements: Vec<S>
}
Run Code Online (Sandbox Code Playgroud)
我也有一个简单的特征,该特征也可用于其他结构:
trait Solid {
fn intersect(&self, ray: f32) -> f32;
}
Run Code Online (Sandbox Code Playgroud)
我想实现Solid的Group,但我希望能够使用Group都为相同的实现的名单Solid和混合实现的名单Solid。基本上我想同时使用Group<Box<Solid>>和Group<Sphere>(Sphere实现Solid)。
目前我正在使用这样的东西:
impl Solid for Group<Box<Solid>> {
fn intersect(&self, ray: f32) -> f32 {
//do stuff
}
}
impl<S: Solid> Solid for Group<S> {
fn intersect(&self, ray: f32) -> f32 {
//do the same stuff, code copy-pasted from previous impl
}
}
Run Code Online (Sandbox Code Playgroud)
这是可行的,但是两次换行相同的代码不是惯用的解决方案。我一定缺少明显的东西吗?
就我而言,我测量了两个特征实现之间的显着性能差异,因此始终使用 …
我想分支并决定在运行时在函数中使用的 Trait 实现(请参见poly_read下面的代码示例)。特征对象是在 if 表达式的分支臂内部构造的,并且只需要在生命周期内存在,poly_read但我需要Box它,因为特征不能从表达式臂内借用,直到我所绑定的绑定为止。尝试将其分配给。
我从逻辑上理解为什么借用结束得太早,但似乎借用检查器应该能够在 if 表达式的值被绑定时将借用扩展到周围范围。我意识到这可能是一个天真的想法,但我想更多地了解为什么这是不可能的。
我对现在的解决方案有点不满意,因为它需要堆分配,尽管我觉得我不应该需要堆分配,因为我只在函数的生命周期内保留该框。我想这是因为在采用分支之前我们不知道reader堆栈上需要的大小,但它不能在编译器中表示为联合,因为我们至少知道最大大小。
顺便说一句,我实际上不知道我对Box堆分配的担忧有多么合理。一般来说,拳击的价值有多贵?
#![feature(io)]
#![feature(path)]
const BYTES: &'static [u8] = &[1u8, 2, 3, 4, 5];
const PATH: &'static str = "/usr/share/dict/words";
use std::old_io::{File, Reader, BufReader};
fn read(r: &mut Reader) {
let some_bytes = r.read_exact(5).unwrap();
assert!(some_bytes.len() == 5);
println!("{:?}", some_bytes);
}
fn poly_read(from_file: bool) {
// Is there any way to extend the lifetime of the ``&mut Reader`` in these branch arms without
// …Run Code Online (Sandbox Code Playgroud) 我无法理解盒装特征的价值是如何形成的.请考虑以下代码:
trait Fooer {
fn foo(&self);
}
impl Fooer for i32 {
fn foo(&self) { println!("Fooer on i32!"); }
}
fn main() {
let a = Box::new(32); // works, creates a Box<i32>
let b = Box::<i32>::new(32); // works, creates a Box<i32>
let c = Box::<Fooer>::new(32); // doesn't work
let d: Box<Fooer> = Box::new(32); // works, creates a Box<Fooer>
let e: Box<Fooer> = Box::<i32>::new(32); // works, creates a Box<Fooer>
}
Run Code Online (Sandbox Code Playgroud)
显然,变体a和b是微不足道的.但是,变量c没有,可能是因为该new函数只采用相同类型的值,而不是这种情况Fooer != i32.变种d和e的工作,这让我怀疑某种自动转换从Box<i32>到Box<Fooer>正在执行. …
我正在将Rust 中的多态性解决方案应用于我的问题。我想使用这个解决方案,Box<_>因为它看起来最直接和简单,但它不起作用。
#[derive(Clone, Copy)]
pub struct NewPost;
#[derive(Clone, Copy)]
pub struct Post;
#[derive(Clone, Copy)]
pub struct PgConnection;
#[derive(Clone, Copy)]
pub struct DBPost;
pub trait DBAdapter {
fn create(self, post: NewPost) -> Post;
fn read(self) -> Vec<Post>;
}
impl DBPost {
// DATABASE classes
pub fn establish_connection(self) -> PgConnection {
unimplemented!()
}
}
impl DBAdapter for DBPost {
fn create(self, _post: NewPost) -> Post {
unimplemented!()
}
fn read(self) -> Vec<Post> {
unimplemented!()
}
}
struct GetPostsCase …Run Code Online (Sandbox Code Playgroud) 我想实例化一个变量,我将把它传递给一个带有T: Write. 它将定义如下:
let outputFile = match matches.opt_str("o") {
Some(fileName) => File::create(fileName).expect("could not open output file"),
None => std::io::stdout()
};
Run Code Online (Sandbox Code Playgroud)
目前,编译器会抱怨 arm ( Filevs. Stdout) 中的不匹配类型。我想要的只是声明outputFile为我可以从Write特征调用任何方法的东西,没有别的。
Rust 允许我这样做还是我必须将整个match表达式作为参数传递给该函数?
I have this pattern that shows up every now and then, but I haven't found a nice way to implement it "correct".
What it is, is I have some variable passed into my function by reference. I don't need to mutate it, I don't need to transfer ownership, I just look at its contents.
However, if the contents are in some state, replace the value with a default value.
For instance say my function accepts a &Vec<String> and if the …