- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在学习这门令人着迷的新语言时,我编写了这段输出 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/
我正在开发一个使用多个 turtle 的滚动游戏。玩家 turtle 根据按键命令在 Y 轴上移动。当危害和好处在 X 轴上移动时,然后循环并改变 Y 轴位置。我尝试定义一个名为 colliding(
我不明白为什么他们不接受这个作为解决方案,他们说这是一个错误的答案:- #include int main(void) { int val=0; printf("Input:- \n
我正在使用基于表单的身份验证。 我有一个注销链接,如下所示: 以及对应的注销方法: public String logout() { FacesContext.getCurren
在 IIS7 应用程序池中有一个设置 Idle-time out 默认是 20 分钟,其中说: Amount of time(in minutes) a worker process will rem
我是一名优秀的程序员,十分优秀!