以下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) 我正在尝试创建一个返回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) 我有一个方法,根据谓词,将返回一个未来或另一个.换句话说,返回未来的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) 我知道我们可以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>”
如何解决这种情况?
我想要一个随机数发生器.既然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) 我正在尝试将数字解码为整数,并且要么获取该数字的迭代器,要么获取空迭代器(如果它不是数字)。我尝试这样做:
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?
我有以下功能,其中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工作原理?
我有一个包含值的结构,我想获得一个对该值进行操作的函数:
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) 我希望能够重复一个过程,在这个过程中,我们正在迭代的集合被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。这有效。
但是,我不想运行 …
我想采用常规迭代器并将其转换为流,以便我可以进行进一步的流处理.麻烦的是我可能有一个迭代器或错误来处理.我觉得我很接近这个:
#[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) rust ×10
traits ×4
asynchronous ×2
future ×2
closures ×1
control-flow ×1
iterator ×1
lifetime ×1
recursion ×1
return-type ×1