기본값을 만들고 해당 내부 버퍼를 반복하는 일반 함수를 작성하려고합니다. " 이 모든 것은 인수 나 반환 값이없는 함수 내에서 발생합니다. 나는 수명이 잘못 선언 된 것 같아서 제대로 작동하도록 올바르게 설정하는 데 어려움을 겪고 있습니다.값이 충분히 길지 않아서 컨테이너를 만들고 항목을 추가 한 다음 항목을 반복합니다.
여기에는 Default
및 IntoIterator
형질뿐만 아니라 하나의 방법이 필요한 Foo
이라는 새로운 형질을 구현하는 예제 유형이 있습니다.
trait Foo<T> {
fn add(&mut self, T);
}
struct FooBar<T> {
buf: Vec<Option<T>>,
len: usize,
}
impl<T> FooBar<T> {
fn new() -> Self {
let buf = Vec::new();
let len = 0;
Self { buf, len }
}
fn iter(&self) -> FooBarIter<T> {
FooBarIter { foo: self, pos: 0 }
}
}
impl<T> Foo<T> for FooBar<T> {
fn add(&mut self, val: T) {
self.buf.push(Some(val));
self.len += 1;
}
}
impl<T> Default for FooBar<T> {
fn default() -> Self {
Self::new()
}
}
impl<'a, T: 'a> IntoIterator for &'a FooBar<T> {
type Item = &'a T;
type IntoIter = FooBarIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
FooBar
은 소유하고있는 벡터에 값을 추가하기 만하면됩니다. non-consuming 반복만을 허용하기 위해서, 나는 밑에있는 Vec
을 빌려서 iteration을 정의했고 반복 중에 "현재"인덱스를 유지하면서 소비자가 빌려 오는 각 요소에 대한 참조를 리턴했다.
struct FooBarIter<'a, T: 'a> {
foo: &'a FooBar<T>,
pos: usize,
}
impl<'a, T> Iterator for FooBarIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.foo.len <= self.pos {
return None;
}
self.pos += 1;
self.foo.buf[self.pos - 1].as_ref()
}
}
일반 함수는, 디폴트 값을 생성 한 다음 참조 (&str
형의) 그 반복하지만 일부 항목을 추가한다. Rust가 빌려준 값인 FooBar
이 충분히 오래 살아 있다고 불평하기 때문에 나는 일생을 잘못 선언 한 것 같습니다. 그러나, 그것은 그것이 기능의 끝까지 살아 간다라고 말한다. 그래서 나는 녹이 실제로 빌려주기를 기대하고있는 길이에 관해서 혼란스러워한다. 여기
fn start<'a, T: 'a>()
where
T: Foo<&'a str> + Default,
&'a T: IntoIterator<Item = &'a &'a str>,
{
let mut f = T::default();
f.add("abcd");
f.add("efgh");
for val in &f {
println!("{}", *val);
}
f.add("ijkl");
for val in &f {
println!("{}", *val);
}
}
fn main() {
start::<FooBar<&str>>();
}
은 함수의 끝 "빌린 값이 때까지만 살고있다"때문
&f
충분히 오래 살지 않는다는 내용의 오류입니다.
error[E0597]: `f` does not live long enough
--> src/main.rs:70:17
|
70 | for val in &f {
| ^does not live long enough
...
73 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 61:1...
--> src/main.rs:61:1
|
61 |/fn start<'a, T: 'a>()
62 | | where
63 | | T: Foo<&'a str> + Default,
64 | | &'a T: IntoIterator<Item = &'a &'a str>,
... |
72 | | }
73 | | }
| |_^
나는 또한 &'a IntoIterator
특성에 대한 서로 다른 수명 매개 변수를 설정하려고했습니다,하지만 난 정말 다른 오류에서 빙빙 돌고 정확한 수명을 설정하는 가까워지고 결국.
FooBar
으로 달성하려는 내용을 더 자세히 설명하려면 여기 FooBar
이 Vec
인 경우 수행하려는 작업의 예가 있습니다.
fn start() {
let mut f = Vec::new();
f.push("abcd");
f.push("efgh");
for val in &f {
println!("{}", *val);
}
f.push("ijkl");
for val in &f {
println!("{}", *val);
}
}
오전 나는 심지어 평생 매개 변수를 알아 내려고 노력과 올바른 궤도에, 아니면 완전히 다른 뭔가?