【发布时间】:2016-04-10 09:35:52
【问题描述】:
我有一个Fibonacci 结构,它可以用作任何实现One、Zero、Add 和Clone 的迭代器。这适用于所有整数类型。
我想将此结构用于BigInteger 类型,这些类型使用Vec 实现并且调用clone() 的成本很高。我想在对T 的两个引用上使用Add,然后返回一个新的T(然后不克隆)。
对于我的一生,我无法制作一个可以编译的...
工作:
extern crate num;
use std::ops::Add;
use std::mem;
use num::traits::{One, Zero};
pub struct Fibonacci<T> {
curr: T,
next: T,
}
pub fn new<T: One + Zero>() -> Fibonacci<T> {
Fibonacci {
curr: T::zero(),
next: T::one(),
}
}
impl<'a, T: Clone + Add<T, Output = T>> Iterator for Fibonacci<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
mem::swap(&mut self.next, &mut self.curr);
self.next = self.next.clone() + self.curr.clone();
Some(self.curr.clone())
}
}
#[test]
fn test_fibonacci() {
let first_12 = new::<i64>().take(12).collect::<Vec<_>>();
assert_eq!(vec![1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144], first_12);
}
期望:
extern crate num;
use std::ops::Add;
use std::mem;
use num::traits::{One, Zero};
pub struct Fibonacci<T> {
curr: T,
next: T,
}
pub fn new<T: One + Zero>() -> Fibonacci<T> {
Fibonacci {
curr: T::zero(),
next: T::one(),
}
}
impl<'a, T: Clone + 'a> Iterator for Fibonacci<T>
where
&'a T: Add<&'a T, Output = T>,
{
type Item = T;
fn next(&mut self) -> Option<T> {
mem::swap(&mut self.next, &mut self.curr);
self.next = &self.next + &self.curr;
Some(self.curr.clone())
}
}
#[test]
fn test_fibonacci() {
let first_12 = new::<i64>().take(12).collect::<Vec<_>>();
assert_eq!(vec![1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144], first_12);
}
这给出了错误
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:27:21
|
27 | self.next = &self.next + &self.curr;
| ^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 25:5...
--> src/main.rs:25:5
|
25 | / fn next(&mut self) -> Option<T> {
26 | | mem::swap(&mut self.next, &mut self.curr);
27 | | self.next = &self.next + &self.curr;
28 | | Some(self.curr.clone())
29 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:27:21
|
27 | self.next = &self.next + &self.curr;
| ^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 19:1...
--> src/main.rs:19:1
|
19 | / impl<'a, T: Clone + 'a> Iterator for Fibonacci<T>
20 | | where
21 | | &'a T: Add<&'a T, Output = T>,
22 | | {
... |
29 | | }
30 | | }
| |_^
note: ...so that types are compatible (expected std::ops::Add, found std::ops::Add<&'a T>)
--> src/main.rs:27:32
|
27 | self.next = &self.next + &self.curr;
| ^
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:27:34
|
27 | self.next = &self.next + &self.curr;
| ^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 25:5...
--> src/main.rs:25:5
|
25 | / fn next(&mut self) -> Option<T> {
26 | | mem::swap(&mut self.next, &mut self.curr);
27 | | self.next = &self.next + &self.curr;
28 | | Some(self.curr.clone())
29 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:27:34
|
27 | self.next = &self.next + &self.curr;
| ^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 19:1...
--> src/main.rs:19:1
|
19 | / impl<'a, T: Clone + 'a> Iterator for Fibonacci<T>
20 | | where
21 | | &'a T: Add<&'a T, Output = T>,
22 | | {
... |
29 | | }
30 | | }
| |_^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:27:34
|
27 | self.next = &self.next + &self.curr;
| ^^^^^^^^^^
【问题讨论】:
-
您可能对std::ops::AddAssign 感兴趣,其 RFC 处于最终评论期:它允许您重载“+=”运算符。这至少可以避免
.clone()调用添加。 -
那将是一个少克隆 :) 我不能同时摆脱两者。 12 周以上,虽然我猜..
-
实际上少了两个克隆:
self.next = self.next.clone() + self.curr.clone();将被self.next += &self.curr;替换。 -
奇怪,我认为“由于要求冲突而无法推断寿命”列出了那些相互冲突的要求。