问题描述
这有效:
let fut = Arc::new(Mutex::new(Box::pin(async { 1 })));
let mut conn_futures = BTreeMap::new(); // implicitly typed
conn_futures.insert(123, fut);
if let Some(fut) = conn_futures.get_mut(&123) {
let fut = fut.clone();
self.pool.spawn(async move {
let mut fut = fut.try_lock().unwrap();
(&mut *fut).await;
});
};
我该如何在结构内部编写相同的内容; conn_futures
是什么类型?根据编译器的说法,它是BTreeMap<i32, impl Future>
,但是无法在结构中编写它:
How do I write the same thing inside a structure; what is the type of conn_futures
? According to the compiler, it's BTreeMap<i32, impl Future>
, but there's no way to write that in a structure:
struct Foo {
conn_futures: BTreeMap<i32, impl Future>, // impl not allow in this position
}
我尝试过:
use futures::{executor::LocalPool, lock::Mutex, task::SpawnExt, Future}; // 0.3.1
use std::{collections::BTreeMap, pin::Pin, sync::Arc};
struct Foo {
conn_futures: BTreeMap<i32, Arc<Mutex<Pin<Box<dyn Future<Output = i32>>>>>>,
}
fn alternative() {
let mut pool = LocalPool::new();
let spawner = pool.spawner();
// Have a structure with the btreemap instead
let mut foo = Foo {
conn_futures: BTreeMap::new(),
};
let fut = Arc::new(Mutex::new(Box::pin(async { 1 })));
foo.conn_futures.insert(123, fut);
if let Some(fut) = foo.conn_futures.get_mut(&123) {
let fut = fut.clone();
spawner.spawn(async move {
let mut fut = fut.try_lock().unwrap();
(&mut *fut).await;
});
};
}
fn main() {
let mut pool = LocalPool::new();
let spawner = pool.spawner();
let fut = Arc::new(Mutex::new(Box::pin(async { 1 })));
let mut conn_futures = BTreeMap::new(); // implicitly typed
conn_futures.insert(123, fut);
if let Some(fut) = conn_futures.get_mut(&123) {
let fut = fut.clone();
spawner.spawn(async move {
let mut fut = fut.try_lock().unwrap();
(&mut *fut).await;
});
};
}
出现错误
error[E0308]: mismatched types
--> src/main.rs:17:34
|
17 | foo.conn_futures.insert(123, fut);
| ^^^ expected trait core::future::future::Future, found opaque type
|
= note: expected type `std::sync::Arc<futures_util::lock::mutex::Mutex<std::pin::Pin<std::boxed::Box<(dyn core::future::future::Future<Output = i32> + 'static)>>>>`
found type `std::sync::Arc<futures_util::lock::mutex::Mutex<std::pin::Pin<std::boxed::Box<impl core::future::future::Future>>>>`
如何在结构中声明conn_futures
的类型?
How do I declare the type of conn_futures
in a struct?
推荐答案
您不能,真的. impl Trait
创建一个匿名的,无法命名的类型.这意味着您不能使用将起作用的显式类型声明变量.
You cannot, really. impl Trait
creates an anonymous, unnameable type. That means that you cannot declare a variable with an explicit type that will work.
主要解决方案是使用 trait对象:
use std::fmt::Display;
fn make_it() -> impl Display {
2
}
struct Example {
it: Box<dyn Display>,
}
impl Example {
fn make() -> Self {
Example {
it: Box::new(make_it()),
}
}
}
您还可以避免使用关联的函数,而应将普通函数与泛型结合使用:
You can also avoid using an associated function and use a plain function instead, coupled with a generic:
use std::fmt::Display;
fn make_it() -> impl Display {
2
}
struct Example<T> {
it: T,
}
impl Example<Box<dyn Display>> {
fn make() -> Self {
Example {
it: Box::new(make_it()),
}
}
}
fn make_example() -> Example<impl Display> {
Example {
it: make_it(),
}
}
只在夜晚
如果您希望使用不稳定的夜间功能,则可以使用 现有类型(RFC 2071):
Nightly only
If you wish to use unstable nightly features, you can use existential types (RFC 2071):
// 1.41.0-nightly (2019-11-24 412f43ac5b4ae8c3599e)
#![feature(type_alias_impl_trait)]
use std::fmt::Display;
type SomeDisplay = impl Display;
fn make_it() -> SomeDisplay {
2
}
struct Example {
it: SomeDisplay,
}
impl Example {
fn make() -> Self {
Example {
it: make_it(),
}
}
}
或者:
// 1.41.0-nightly (2019-11-24 412f43ac5b4ae8c3599e)
#![feature(type_alias_impl_trait)]
use std::fmt::Display;
fn make_it() -> impl Display {
2
}
struct Example<T> {
it: T,
}
type SomeDisplay = impl Display;
impl Example<SomeDisplay> {
fn make() -> Self {
Example { it: make_it() }
}
}
另请参阅:
- 返回Iterator(或其他任何特征)的正确方法是什么?
- 为什么不能使用impl trait返回多个/条件类型?
- 是否可以在特征定义中使用"impl Trait"作为函数的返回类型?
- 什么使特质对象"成为东西?
- 在板条箱的API中发布具体类型而不是"impl trait"的好处是什么?
- What is the correct way to return an Iterator (or any other trait)?
- Why can impl trait not be used to return multiple / conditional types?
- Is it possible to use `impl Trait` as a function's return type in a trait definition?
- What makes something a "trait object"?
- What is the advantage of publishing a concrete type in a crate's API instead of `impl trait`?
这篇关于如何在结构中存储`impl Trait`类型的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!