以下Rust代码编译并运行没有任何问题.
fn main() {
let text = "abc";
println!("{}", text.split(' ').take(2).count());
}
Run Code Online (Sandbox Code Playgroud)
在那之后,我尝试了类似的东西....但它没有编译
fn main() {
let text = "word1 word2 word3";
println!("{}", to_words(text).take(2).count());
}
fn to_words(text: &str) -> &Iterator<Item = &str> {
&(text.split(' '))
}
Run Code Online (Sandbox Code Playgroud)
主要问题是我不确定函数to_words()应该具有什么返回类型.编译器说:
error[E0599]: no method named `count` found for type `std::iter::Take<std::iter::Iterator<Item=&str>>` in the current scope
--> src/main.rs:3:43
|
3 | println!("{}", to_words(text).take(2).count());
| ^^^^^
|
= note: the method `count` exists but the following trait bounds were not satisfied:
`std::iter::Iterator<Item=&str> : std::marker::Sized`
`std::iter::Take<std::iter::Iterator<Item=&str>> …Run Code Online (Sandbox Code Playgroud) 我曾经有类似的东西:
struct Foo {
pub foo: |usize| -> usize,
}
Run Code Online (Sandbox Code Playgroud)
现在闭包语法已经过时了.我可以这样做:
struct Foo<F: FnMut(usize) -> usize> {
pub foo: F,
}
Run Code Online (Sandbox Code Playgroud)
但那么Foo我创建的对象的类型是什么?
let foo: Foo<???> = Foo { foo: |x| x + 1 };
Run Code Online (Sandbox Code Playgroud)
我也可以使用参考:
struct Foo<'a> {
pub foo: &'a mut FnMut(usize) -> usize,
}
Run Code Online (Sandbox Code Playgroud)
但我觉得它的速度较慢,因为a)指针deref,以及b)现在对于FnMut实际最终被使用的类型没有专门化.
在搜索有关保守impl trait的文档时,我发现了这个例子:
struct A {
x: [(u32, u32); 10]
}
impl A {
fn iter_values<'a>(&'a self) -> impl 'a + Iterator<Item = u32> {
self.x.iter().map(|a| a.0)
}
}
Run Code Online (Sandbox Code Playgroud)
生命周期'a在返回类型中意味着什么?
我知道关于终身受限Box的这个问题,但我认为用例是不同的.如果我理解答案:
特质对象仅对生命周期'a有效
这意味着生活在堆中某处的特征对象将在一生中持续'a.
但在这里,这不是一个特质对象,而是一个生活在堆栈中的具体对象.因此编译器不需要提供有关其生命周期的提示.
我对此缺少什么?
我想我了解生命周期如何与函数参数/输出和结构一起工作,因为这些情况在书中(以及在nomicon 中进一步解释),但我不明白生命周期如何用于类型边界。例如:
trait Min<Elmt> {
fn get_min(&self) -> Elmt;
}
impl<T, Elmt> Min<Elmt> for T
where
&T: IntoIterator<Item = Elmt>,
Elmt: Ord,
{
fn get_min(&self) -> Elmt {
let mut iter = self.into_iter();
match iter.next() {
None => panic!("Empty List"),
Some(x) => iter.fold(x, |acc, y| acc.min(y)),
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我要求类型T满足以下属性:它的任何引用都必须实现IntoIterator<Item = Ord>. 这段代码无法编译,因为 Rust 想要&T有一个生命周期,而我不知道为什么。该where子句应该只确保某些东西是某种类型,这是在编译时完成的。生命周期/引用是如何产生的?确保&T实现类型的T实现IntoIterator与悬空指针或内存泄漏无关。
来自 Rust Discord …
我有一个包含值的结构,我想获得一个对该值进行操作的函数:
struct Returner {
val: i32,
}
impl<'a> Returner {
fn get(&'a self) -> Box<Fn(i32) -> i32> {
Box::new(|x| x + self.val)
}
}
Run Code Online (Sandbox Code Playgroud)
编译失败:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:7:18
|
7 | Box::new(|x| x + self.val)
| ^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 5:1...
--> src/main.rs:5:1
|
5 | impl<'a> Returner {
| ^^^^^^^^^^^^^^^^^
= note: ...so that the types are …Run Code Online (Sandbox Code Playgroud) 为了学习Rust语言,我正在使用一个旧的C++库,我已经躺在那里并尝试将其转换为Rust.它使用了很多C++ 11闭包,我在翻译概念方面遇到了一些困难.
在C++中我有这样的事情:
// library.h
struct Event {
// just some data
};
class Object {
public:
// ...
std::function<void(Event&)>& makeFunc(std::string& s) {
return m_funcs[s];
}
// ...
private:
// ...
std::map<std::string, std::function<void(Event&)>> m_funcs;
// ...
};
// main.cpp using the library
int main()
{
Object foo;
foo.makeFunc("func1") = [&]{
// do stuff
};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我遇到问题的部分是将函数正确存储在Rust HashMap集合中.我试过这个:
struct Event;
struct Object {
m_funcs : HashMap<String, FnMut(&Event)>
}
impl Object {
// send f as another parameter rather than …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用创建的结构main()并将其传递给返回盒装Future. 然而,我遇到了终身和借贷问题,似乎无法彻底解决这个问题。
这是我的结构和函数:
extern crate futures; // 0.1.21
extern crate tokio_core; // 0.1.17
use futures::{future::ok, Future};
pub struct SomeStruct {
some_val: u32,
}
impl SomeStruct {
pub fn do_something(&self, value: u32) -> u32 {
// Do some work
return self.some_val + value;
}
}
fn main() {
let core = tokio_core::reactor::Core::new().unwrap();
let my_struct = SomeStruct { some_val: 10 };
let future = get_future(&my_struct);
core.run(future);
let future2 = get_future(&my_struct);
core.run(future2);
}
fn get_future(some_struct: &SomeStruct) -> Box<Future<Item = …Run Code Online (Sandbox Code Playgroud) 进一步IntoIterator按照Rust的书实现包装矢量的示例,我还尝试根据以下代码(Playground链接)实现IntoIterator以引用包装器:
struct VecWrapper(Vec<i32>);
impl VecWrapper {
fn iter(&'static self) -> Iter {
Iter(Box::new(self.0.iter()))
}
}
struct Iter(Box<Iterator<Item = &'static i32>>);
impl Iterator for Iter {
type Item = &'static i32;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl IntoIterator for &'static VecWrapper {
type Item = &'static i32;
type IntoIter = Iter;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
fn main() {
// let test = vec![1, 2, 3]; // …Run Code Online (Sandbox Code Playgroud)