gpt4 book ai didi

iterator - 迭代器字段的生命周期

转载 作者:行者123 更新时间:2023-11-29 08:00:05 25 4
gpt4 key购买 nike

在学习这门令人着迷的新语言时,我编写了这段输出 0 到 10 乘以 3 的代码:

pub struct Multiplier {
factor : int,
current : int
}
impl Multiplier {
pub fn new(factor : int) -> Multiplier {
Multiplier {
factor: factor,
current: 0
}
}
}
impl Iterator<int> for Multiplier {
fn next(&mut self) -> Option<int> {
if self.current > 10 {
None
}
else {
let current = self.current;
self.current += 1;
Some(current * self.factor)
}
}
}

struct Holder {
x : Multiplier
}
impl Holder {
pub fn new(factor : int) -> Holder {
Holder {
x : Multiplier::new(factor)
}
}

fn get_iterator(&self) -> Multiplier {
self.x
}
}

fn main() {
let mut three_multiplier = Holder::new(3).get_iterator();
for item in three_multiplier {
println!("{}", item);
}
}

如果我从这里更改 Holder

struct Holder {
x : Multiplier
}

为此:

struct Holder {
x : Iterator<int>
}

我收到一个编译警告:

<anon>:27:9: 27:22 error: explicit lifetime bound required
<anon>:27 x : Iterator<int>
^~~~~~~~~~~~~

谁能解释为什么更改字段类型需要明确的生命周期?我知道如何标记生命周期,但我不确定为什么编译器要我这样做。

最佳答案

您可以通过这种方式添加生命周期:

struct Holder<'a> {
x: Iterator<int>+'a
}

但请注意,通过这种方式,Holder 结构未调整大小,因为它包含未调整大小的特征对象。这严重限制了您可以对该类型执行的操作:例如,您不能直接返回 Holder

你可以通过让 Holder 接受一个类型参数来解决这个问题:

struct Holder<T> where T: Iterator<int> {
x : T
}

让我们更改 get_iterator 以使用类型参数:

impl<T> Holder<T> where T: Iterator<int>+Copy {
fn get_iterator(&self) -> T {
self.x
}
}

注意:我在此处添加了 Copy 绑定(bind),因为 get_iterator 当前返回一个副本。您可以通过使 get_iterator 返回 &T 来避免绑定(bind)。

至于new,你必须完全重新设计它。如果我们保持原样,如果我们将其称为 Holder::new,编译器会报错,因为 Holder 现在有一个类型参数,编译器无法推断类型,因为new 不使用任何。为了解决这个问题,我们可以通过使用特征来提供构造函数来使 new 通用:

trait FactorCtor {
fn new(factor: int) -> Self;
}

然后更改 new 以使用该特征:

impl<T> Holder<T> where T: Iterator<int>+FactorCtor {
pub fn new(factor : int) -> Holder<T> {
Holder {
x : FactorCtor::new(factor)
}
}
}

因为我们在这个程序中只有一个 FactorCtor 的实现,编译器在调用 Holder::new 时设法推断出 T。如果我们添加另一个实现,例如加法器:

pub struct Adder {
factor : int,
current : int
}
impl FactorCtor for Adder {
fn new(factor: int) -> Adder {
Adder {
factor: factor,
current: 0
}
}
}
impl Iterator<int> for Adder {
fn next(&mut self) -> Option<int> {
if self.current > 10 {
None
}
else {
let current = self.current;
self.current += 1;
Some(current + self.factor)
}
}
}

然后我们得到一个编译器错误:

<anon>:72:9: 72:29 error: unable to infer enough type information about `_`; type annotations required
<anon>:72 let mut three_multiplier = Holder::new(3).get_iterator();
^~~~~~~~~~~~~~~~~~~~

我们可以通过显式指定 T 来解决这个问题:

fn main() {
let mut three_multiplier = Holder::<Multiplier>::new(3).get_iterator();
for item in three_multiplier {
println!("{}", item);
}
}

关于iterator - 迭代器字段的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26949265/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com