Rust 显示预期的特征对象“dyn Future”,在将函数作为参数传递时发现不透明类型
Rust showing expected trait object `dyn Future`, found opaque type when passing function as a param
use std::io::prelude::*;
use std::net::TcpListener;
use std::net::TcpStream;
use std::time::Duration;
// pyO3 module
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use std::future::Future;
#[pyfunction]
pub fn start_server() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
let pool = ThreadPool::new(4);
for stream in listener.incoming() {
let stream = stream.unwrap();
pool.execute(|| {
let rt = tokio::runtime::Runtime::new().unwrap();
handle_connection(stream, rt, &test_helper);
});
}
}
#[pymodule]
pub fn roadrunner(_: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(start_server))?;
Ok(())
}
async fn read_file(filename: String) -> String {
let con = tokio::fs::read_to_string(filename).await;
con.unwrap()
}
async fn test_helper(contents: &mut String, filename: String) {
// this function will accept custom function and return
*contents = tokio::task::spawn(read_file(filename.clone()))
.await
.unwrap();
}
pub fn handle_connection(
mut stream: TcpStream,
runtime: tokio::runtime::Runtime,
test: &dyn Fn(&mut String, String) -> (dyn Future<Output = ()> + 'static),
) {
let mut buffer = [0; 1024];
stream.read(&mut buffer).unwrap();
let get = b"GET / HTTP/1.1\r\n";
let sleep = b"GET /sleep HTTP/1.1\r\n";
let (status_line, filename) = if buffer.starts_with(get) {
("HTTP/1.1 200 OK", "hello.html")
} else if buffer.starts_with(sleep) {
thread::sleep(Duration::from_secs(5));
("HTTP/1.1 200 OK", "hello.html")
} else {
("HTTP/1.1 404 NOT FOUND", "404.html")
};
let mut contents = String::new();
let future = test_helper(&mut contents, String::from(filename));
runtime.block_on(future);
let response = format!(
"{}\r\nContent-Length: {}\r\n\r\n{}",
status_line,
contents.len(),
contents
);
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}
我正在尝试创建一个模块,我需要在其中传递一个异步函数作为参数。我已经传递了该元素,但我无法从错误消息中推断出我应该做什么。它告诉我类型推断中存在一些不匹配。
这是我在 cargo check
上收到的错误消息
error[E0271]: type mismatch resolving `for<'r> <for<'_> fn(&mut String, String) -> impl Future {test_helper} as FnOnce<(&'r mut String, String)>>::Output == (dyn Future<Output = ()> + 'static)`
--> src/lib.rs:124:43
|
124 | handle_connection(stream, rt, &test_helper);
| ^^^^^^^^^^^^ expected trait object `dyn Future`, found opaque type
...
140 | async fn test_helper(contents: &mut String, filename: String) {
| - checked the `Output` of this `async fn`, found opaque type
|
= note: while checking the return type of the `async fn`
= note: expected trait object `(dyn Future<Output = ()> + 'static)`
found opaque type `impl Future`
= note: required for the cast to the object type `dyn for<'r> Fn(&'r mut String, String) -> (dyn Future<Output = ()> + 'static)`
error: aborting due to previous error
请让我知道这里应该进行哪些更改。提前致谢。
您正在编写一个函数类型 returns 一个 dyn
类型,不是对它的引用,而是未调整大小的类型本身,这是不可能的。每次你想写这样的东西时,尝试使用泛型代替:
pub fn handle_connection<F>(
mut stream: TcpStream,
runtime: tokio::runtime::Runtime,
test: &dyn Fn(&mut String, String) -> F,
)
where F: Future<Output = ()> + 'static
现在失败并出现这个奇怪的错误:
error[E0308]: mismatched types
--> src/lib.rs:19:43
|
19 | handle_connection(stream, rt, &test_helper);
| ^^^^^^^^^^^^ one type is more general than the other
|
= note: expected associated type `<for<'_> fn(&mut String, String) -> impl Future {test_helper} as FnOnce<(&mut String, String)>>::Output`
found associated type `<for<'_> fn(&mut String, String) -> impl Future {test_helper} as FnOnce<(&mut String, String)>>::Output`
但这也是预料之中的,你的未来正在参考你即将通过的 &mut String
,所以它不再是 'static
。解决方案只是添加一个生命周期通用参数:
pub fn handle_connection<'a, F>(
mut stream: TcpStream,
runtime: tokio::runtime::Runtime,
test: &dyn Fn(&'a mut String, String) -> F,
)
where F: Future<Output = ()> + 'a
现在应该可以编译了。
use std::io::prelude::*;
use std::net::TcpListener;
use std::net::TcpStream;
use std::time::Duration;
// pyO3 module
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use std::future::Future;
#[pyfunction]
pub fn start_server() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
let pool = ThreadPool::new(4);
for stream in listener.incoming() {
let stream = stream.unwrap();
pool.execute(|| {
let rt = tokio::runtime::Runtime::new().unwrap();
handle_connection(stream, rt, &test_helper);
});
}
}
#[pymodule]
pub fn roadrunner(_: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(start_server))?;
Ok(())
}
async fn read_file(filename: String) -> String {
let con = tokio::fs::read_to_string(filename).await;
con.unwrap()
}
async fn test_helper(contents: &mut String, filename: String) {
// this function will accept custom function and return
*contents = tokio::task::spawn(read_file(filename.clone()))
.await
.unwrap();
}
pub fn handle_connection(
mut stream: TcpStream,
runtime: tokio::runtime::Runtime,
test: &dyn Fn(&mut String, String) -> (dyn Future<Output = ()> + 'static),
) {
let mut buffer = [0; 1024];
stream.read(&mut buffer).unwrap();
let get = b"GET / HTTP/1.1\r\n";
let sleep = b"GET /sleep HTTP/1.1\r\n";
let (status_line, filename) = if buffer.starts_with(get) {
("HTTP/1.1 200 OK", "hello.html")
} else if buffer.starts_with(sleep) {
thread::sleep(Duration::from_secs(5));
("HTTP/1.1 200 OK", "hello.html")
} else {
("HTTP/1.1 404 NOT FOUND", "404.html")
};
let mut contents = String::new();
let future = test_helper(&mut contents, String::from(filename));
runtime.block_on(future);
let response = format!(
"{}\r\nContent-Length: {}\r\n\r\n{}",
status_line,
contents.len(),
contents
);
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}
我正在尝试创建一个模块,我需要在其中传递一个异步函数作为参数。我已经传递了该元素,但我无法从错误消息中推断出我应该做什么。它告诉我类型推断中存在一些不匹配。
这是我在 cargo check
error[E0271]: type mismatch resolving `for<'r> <for<'_> fn(&mut String, String) -> impl Future {test_helper} as FnOnce<(&'r mut String, String)>>::Output == (dyn Future<Output = ()> + 'static)`
--> src/lib.rs:124:43
|
124 | handle_connection(stream, rt, &test_helper);
| ^^^^^^^^^^^^ expected trait object `dyn Future`, found opaque type
...
140 | async fn test_helper(contents: &mut String, filename: String) {
| - checked the `Output` of this `async fn`, found opaque type
|
= note: while checking the return type of the `async fn`
= note: expected trait object `(dyn Future<Output = ()> + 'static)`
found opaque type `impl Future`
= note: required for the cast to the object type `dyn for<'r> Fn(&'r mut String, String) -> (dyn Future<Output = ()> + 'static)`
error: aborting due to previous error
请让我知道这里应该进行哪些更改。提前致谢。
您正在编写一个函数类型 returns 一个 dyn
类型,不是对它的引用,而是未调整大小的类型本身,这是不可能的。每次你想写这样的东西时,尝试使用泛型代替:
pub fn handle_connection<F>(
mut stream: TcpStream,
runtime: tokio::runtime::Runtime,
test: &dyn Fn(&mut String, String) -> F,
)
where F: Future<Output = ()> + 'static
现在失败并出现这个奇怪的错误:
error[E0308]: mismatched types
--> src/lib.rs:19:43
|
19 | handle_connection(stream, rt, &test_helper);
| ^^^^^^^^^^^^ one type is more general than the other
|
= note: expected associated type `<for<'_> fn(&mut String, String) -> impl Future {test_helper} as FnOnce<(&mut String, String)>>::Output`
found associated type `<for<'_> fn(&mut String, String) -> impl Future {test_helper} as FnOnce<(&mut String, String)>>::Output`
但这也是预料之中的,你的未来正在参考你即将通过的 &mut String
,所以它不再是 'static
。解决方案只是添加一个生命周期通用参数:
pub fn handle_connection<'a, F>(
mut stream: TcpStream,
runtime: tokio::runtime::Runtime,
test: &dyn Fn(&'a mut String, String) -> F,
)
where F: Future<Output = ()> + 'a
现在应该可以编译了。