相关疑难解决方法(0)

返回迭代器(或任何其他特征)的正确方法是什么?

以下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)

rust

92
推荐指数
1
解决办法
2万
查看次数

如何从方法返回特征实例?

我正在尝试创建一个返回Shader特征实例的函数.这是我极为简化的代码:

trait Shader {}

struct MyShader;
impl Shader for MyShader {}

struct GraphicsContext;

impl GraphicsContext {
    fn create_shader(&self) -> Shader {
        let shader = MyShader;
        shader
    }
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

error[E0277]: the trait bound `Shader + 'static: std::marker::Sized` is not satisfied
  --> src/main.rs:10:32
   |
10 |     fn create_shader(&self) -> Shader {
   |                                ^^^^^^ `Shader + 'static` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `Shader …
Run Code Online (Sandbox Code Playgroud)

traits rust

25
推荐指数
2
解决办法
1万
查看次数

我如何有条件地退回不同类型的期货?

我有一个方法,根据谓词,将返回一个未来或另一个.换句话说,返回未来的if-else表达式:

extern crate futures; // 0.1.23

use futures::{future, Future};

fn f() -> impl Future<Item = usize, Error = ()> {
    if 1 > 0 {
        future::ok(2).map(|x| x)
    } else {
        future::ok(10).and_then(|x| future::ok(x + 2))
    }
}
Run Code Online (Sandbox Code Playgroud)

这不编译:

error[E0308]: if and else have incompatible types
  --> src/lib.rs:6:5
   |
6  | /     if 1 > 0 {
7  | |         future::ok(2).map(|x| x)
8  | |     } else {
9  | |         future::ok(10).and_then(|x| future::ok(x + 2))
10 | |     }
   | |_____^ expected …
Run Code Online (Sandbox Code Playgroud)

asynchronous future control-flow rust

13
推荐指数
1
解决办法
1463
查看次数

如何处理 flat_map 中的结果

我知道我们可以collect用来将 aResult从内部移动到外部,例如:

fn produce_result(my_struct: &MyStruct) -> Result<MyStruct, Error>;

let my_results: Vec<MyStruct> = vec![];
let res = my_results.iter().map(|my_struct| produce_result(&my_struct)).collect::<Result<Vec<MyStruct>, Error>>;
Run Code Online (Sandbox Code Playgroud)

它将错误从闭包传播到外部。

但是,这种方法在以下flat_map情况下不起作用(Rust playground):

fn produce_result(my_struct: &MyStruct) -> Result<Vec<MyStruct>, Error>;

let my_results: Vec<MyStruct> = vec![];
let res = my_results.iter().flat_map(|my_struct| produce_result(&my_struct)).collect::<Result<Vec<MyStruct>, Error>>;
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:“std::result::Result<std::vec::Vec<MyStruct>, Error>不能从类型元素的迭代器构建类型集合std::vec::Vec<MyStruct>

如何解决这种情况?

rust

10
推荐指数
2
解决办法
2045
查看次数

为什么impl trait不能用于返回多个/条件类型?

我想要一个随机数发生器.既然OsRng::new()可能会失败,我想回到以下情况,thread_rng()如果我必须:

extern crate rand; // 0.6.5

use rand::{rngs::OsRng, thread_rng, RngCore};

fn rng() -> impl RngCore {
    match OsRng::new() {
        Ok(rng) => rng,
        Err(e) => thread_rng(),
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到此错误消息,我无法理解:

error[E0308]: match arms have incompatible types
 --> src/lib.rs:6:5
  |
6 | /     match OsRng::new() {
7 | |         Ok(rng) => rng,
8 | |         Err(e) => thread_rng(),
  | |                   ------------ match arm with an incompatible type
9 | |     }
  | |_____^ expected struct `rand::rngs::OsRng`, found struct `rand::prelude::ThreadRng` …
Run Code Online (Sandbox Code Playgroud)

return-type traits rust

8
推荐指数
2
解决办法
1208
查看次数

如何将 Option&lt;T&gt; 转换为零个或一个元素的迭代器?

我正在尝试将数字解码为整数,并且要么获取该数字的迭代器,要么获取空迭代器(如果它不是数字)。我尝试这样做:

let ch = '1';
ch.to_digit(10).map(once).unwrap_or(empty())
Run Code Online (Sandbox Code Playgroud)

这不能编译。我收到以下错误消息:

let ch = '1';
ch.to_digit(10).map(once).unwrap_or(empty())
Run Code Online (Sandbox Code Playgroud)

我有什么方法可以告诉我.unwrap_or(...),我不关心实际类型,但我会得到一个实现Iterator

traits rust

5
推荐指数
1
解决办法
2017
查看次数

Rust impl Trait 作为函数返回类型

我有以下功能,其中Command有一个特征

pub fn parse_arguments(matches: ArgMatches) -> Result<impl Command, &'static str>
Run Code Online (Sandbox Code Playgroud)

在函数体内,我想根据参数返回 Command 的不同实现,例如

match args.subcommand() {
    ("init", Some(args)) => {
        Ok(Init::new(args))
    }
    ("btc", Some(args)) => {
        Ok(ImportBtc::new(args))
    },
    ("grin", Some(args)) => {
        Ok(ImportGrin::new(args))
    },
    _ => Err ("Invalid subcommand supplied")
}
Run Code Online (Sandbox Code Playgroud)

编译将失败并出现错误:

expected struct `commands::cmd_types::Init`, found struct `commands::cmd_types::ImportBtc`
Run Code Online (Sandbox Code Playgroud)

返回线也类似ImportGrin

我是否误解了impl Trait工作原理?

rust

5
推荐指数
1
解决办法
2824
查看次数

如何从具有结构引用的方法返回一个盒装闭包?

我有一个包含值的结构,我想获得一个对该值进行操作的函数:

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)

closures lifetime rust

4
推荐指数
1
解决办法
770
查看次数

如何在没有运行时多态性的情况下对迭代器执行 N 次 `flat_map`(或类似操作)?

我希望能够重复一个过程,在这个过程中,我们正在迭代的集合被n多次更改。n仅在运行时已知,并且可由用户指定,因此我们无法将其硬编码到类型中。

通过collect在迭代之间使用中间数据结构的方法是可能的,如下所示:

let n = 10;

let mut vec1 = vec![1, 2, 3];
{
    for _index in 0..n {
        let temp_vec = vec1.into_iter().flat_map(|x| vec![x, x * 2]).collect();
        vec1 = temp_vec;
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,这似乎很浪费,因为我们正在创建中间数据结构,所以我继续寻找直接链接迭代器的解决方案。

起初我认为一个人可以做这样的事情:

let mut iter = vec![1, 2, 3].into_iter();
for index in 0..n {
    iter = iter.flat_map(|x| vec![x, x * 2].into_iter());
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为在 Rust 中,迭代器上的所有函数都返回它们自己类型的“复合迭代器”结构。(例如,在 Haskell 中,迭代器上的函数返回适当类型的结果迭代器,它不会变成“越来越大的复合类型”。)将其重写为递归函数也有类似的问题,因为 (a) 我正在返回“某种类型” Iterator' 的类型(接近?)-由于递归而无法手动写出,并且(b)这种类型在基本情况下与递归情况不同。

我发现这个问题是关于有条件地返回一个或另一个迭代器类型,以及impl Iterator用于指示我们返回一些实现 Iterator 特性的具体类型,但我们不关心它的确切性质。与链接答案中的代码类似的示例已在以下代码中实现为maybe_flatmap。这有效。

但是,我不想运行 …

recursion iterator traits rust recursive-type

3
推荐指数
1
解决办法
577
查看次数

如何在成功时将迭代器转换为流或在失败时将空流转换为空流?

我想采用常规迭代器并将其转换为流,以便我可以进行进一步的流处理.麻烦的是我可能有一个迭代器或错误来处理.我觉得我很接近这个:

#[macro_use]
extern crate log;
extern crate futures; // 0.1.21
extern crate tokio;

use futures::prelude::*;
use futures::{future, stream};
use std::fmt::Debug;
use std::net::{SocketAddr, ToSocketAddrs};

fn resolve(addrs: impl ToSocketAddrs + Debug) -> impl Stream<Item = SocketAddr, Error = ()> {
    match addrs.to_socket_addrs() {
        Ok(iter) => stream::unfold(iter, |iter| match iter.next() {
            Some(a) => Some(future::ok((a, iter))),
            None => None,
        }),
        Err(e) => {
            error!("could not resolve socket addresses {:?}: {:?}", addrs, e);
            stream::empty()
        }
    }
}

fn main() {
    let task = …
Run Code Online (Sandbox Code Playgroud)

asynchronous future rust

2
推荐指数
1
解决办法
476
查看次数