我有一个值,我想在我自己的类型中存储该值以及对该值内部内容的引用:
struct Thing {
count: u32,
}
struct Combined<'a>(Thing, &'a u32);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing { count: 42 };
Combined(thing, &thing.count)
}
Run Code Online (Sandbox Code Playgroud)
有时候,我有一个值,我想在同一个结构中存储该值和对该值的引用:
struct Combined<'a>(Thing, &'a Thing);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing::new();
Combined(thing, &thing)
}
Run Code Online (Sandbox Code Playgroud)
有时,我甚至没有参考该值,我得到同样的错误:
struct Combined<'a>(Parent, Child<'a>);
fn make_combined<'a>() -> Combined<'a> {
let parent = Parent::new();
let child = parent.child();
Combined(parent, child)
}
Run Code Online (Sandbox Code Playgroud)
在每种情况下,我都会收到一个错误,即其中一个值"活不够长".这个错误是什么意思?
我是Rust的新手并阅读了Rust编程语言,在错误处理部分有一个"案例研究",描述了一个程序,使用csv和rustc-serialize库(getopts用于参数解析)从CSV文件中读取数据.
作者编写了一个函数search,该函数使用一个csv::Reader对象逐步执行csv文件的行,并将那些"city"字段与指定值匹配的条目收集到一个向量中并返回它.我采取了与作者略有不同的方法,但这不应该影响我的问题.我的(工作)函数看起来像这样:
extern crate csv;
extern crate rustc_serialize;
use std::path::Path;
use std::fs::File;
fn search<P>(data_path: P, city: &str) -> Vec<DataRow>
where P: AsRef<Path>
{
let file = File::open(data_path).expect("Opening file failed!");
let mut reader = csv::Reader::from_reader(file).has_headers(true);
reader.decode()
.map(|row| row.expect("Failed decoding row"))
.filter(|row: &DataRow| row.city == city)
.collect()
}
Run Code Online (Sandbox Code Playgroud)
在DataRow类型仅仅是一个记录,
#[derive(Debug, RustcDecodable)]
struct DataRow {
country: String,
city: String,
accent_city: String,
region: String,
population: Option<u64>, …Run Code Online (Sandbox Code Playgroud) 我试图迭代stdin中的字符.该Read.chars()方法实现了这一目标,但不稳定.显而易见的替代方法是使用Read.lines()a flat_map将其转换为字符迭代器.
这似乎应该有效,但不会,导致borrowed value does not live long enough错误.
use std::io::BufRead;
fn main() {
let stdin = std::io::stdin();
let mut lines = stdin.lock().lines();
let mut chars = lines.flat_map(|x| x.unwrap().chars());
}
Run Code Online (Sandbox Code Playgroud)
这在Rust中的逐字符读取文件中提到,但它并没有真正解释原因.
我特别困惑的是它与文档中flat_map的示例有何不同,后者用于flat_map应用于.chars()字符串向量.我真的不明白这应该有什么不同.我看到的主要区别是我的代码也需要调用unwrap(),但是将最后一行更改为以下代码也不起作用:
let mut chars = lines.map(|x| x.unwrap());
let mut chars = chars.flat_map(|x| x.chars());
Run Code Online (Sandbox Code Playgroud)
它在第二行失败,所以问题似乎不是unwrap.
为什么最后一行不起作用,当文档中非常相似的行没有?有没有办法让这个工作?
以下代码无法编译:
use std::str::Chars;
struct Chunks {
remaining: Chars,
}
impl Chunks {
fn new(s: String) -> Self {
Chunks {
remaining: s.chars(),
}
}
}
Run Code Online (Sandbox Code Playgroud)
错误是:
use std::str::Chars;
struct Chunks {
remaining: Chars,
}
impl Chunks {
fn new(s: String) -> Self {
Chunks {
remaining: s.chars(),
}
}
}
Run Code Online (Sandbox Code Playgroud)
Chars不拥有要迭代的字符,也不能超过其&str或String从其创建的字符。
是否存在Chars不需要生存期参数的私有版本,或者我必须自己保留Vec<char>和索引?
这是我所能得到的,使用rental,部分基于How can I store a Chars iterator in the same struct as the String it iterateing? 。这里的区别在于,get_iter锁定成员的方法必须采用可变的自引用。
我与使用租赁无关:我对使用reffers或owning_ref 的解决方案同样满意。
出现PhantomData在这里只是为了与被迭代的事物MyIter具有正常的生命周期关系。MyIterable
我还尝试更改#[rental]为并更改to#[rental(deref_mut_suffix)]的返回类型,但这给了我源自宏的其他终身错误,我无法破译。MyIterable.get_iterBox<Iterator<Item=i32> + 'a>
#[macro_use]
extern crate rental;
use std::marker::PhantomData;
pub struct MyIterable {}
impl MyIterable {
// In the real use-case I can't remove the 'mut'.
pub fn get_iter<'a>(&'a mut self) -> MyIter<'a> {
MyIter {
marker: PhantomData,
}
} …Run Code Online (Sandbox Code Playgroud)