デフォルト値を作成し、内部のバッファを反復する汎用関数を作成しようとしています。 "これは、引数も戻り値もない関数内で起こります。私は生涯が間違って宣言されているように見え、これを正しく機能させるには苦労している。コンテナを作成し、アイテムを追加し、アイテムを反復する汎用関数で値が十分に長く存続しない
Default
およびIntoIterator
形質を実装するタイプのタイプと、1つのメソッドを必要とする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
は、所有するベクトルに値を追加するだけです。無駄な反復のみを可能にするために、私は反復子を定義して、基礎となるVec
を借用し、反復中に "現在の"インデックスを維持し、消費者が借りる各要素への参照を返します。
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
が十分に長く生きていないと訴えるので、私は生涯を間違って宣言したようです。しかし、それは機能の終わりまで生きていると言われています。だから、Rustが実際に借りることを期待している時間は混乱しています。ここで
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);
}
}
生涯のパラメータを把握しようとすると正しい軌道上にいるのですか、それとも完全に何かありますか?