我发现,当泛型关系错综复杂时,仅通过阅读简单的源代码是无法追踪的.
有没有办法透露编译器对特定泛型 struct 或函数的实例化轨迹?
Elaborated:
感谢你对这个问题感兴趣.它在这里进行了详细阐述.我最近在研究经度 crate .因此,以它为例.
use warp::Filter;
async fn handler_without_parameter() -> Result<impl warp::Reply, warp::Rejection> {
Ok(warp::reply::json(&"dumb".to_string()))
}
fn main() {
let get_items = warp::get()
.and(warp::path("/"))
.and(warp::path::end())
.and_then(handler_without_parameter); //Ok here
}
async fn handler_without_parameter() -> Result<impl warp::Reply, warp::Rejection> {
Ok(warp::reply::json(&"dumb".to_string()))
}
fn main() {
let para: HashMap<String, String> = HashMap::new();
let para_filter = warp::any().map(move || para.clone()); // A filter with data
let get_items = warp::get()
.and(warp::path("/"))
.and(warp::path::end())
.and(para_filter) //chain with the data filter
.and_then(handler_without_parameter); // error[E0593]: function is expected to take 1 argument, but it takes 0 arguments
}
在链接筛选器(它与数据一起)之后,方法and_then
的参数预期为1个自变量.我对and_then
的这个需求变化很好奇,所以我试着弄清楚这个方法的单形化过程.
https://docs.rs/warp/0.3.5/warp/trait.Filter.html#method.and_then个
fn and<F>(self, other: F) -> And<Self, F>
where
Self: Sized,
<Self::Extract as Tuple>::HList: Combine<<F::Extract as Tuple>::HList>,
F: Filter + Clone,
F::Error: CombineRejection<Self::Error>,
{
And {
first: self,
second: other,
}
}
fn and_then<F>(self, fun: F) -> AndThen<Self, F>
where
Self: Sized,
F: Func<Self::Extract> + Clone,
F::Output: TryFuture + Send,
<F::Output as TryFuture>::Error: CombineRejection<Self::Error>,
{
AndThen {
filter: self,
callback: fun,
}
}
基本特征是:
pub trait FilterBase {
type Extract: Tuple; // + Send;
type Error: IsReject;
type Future: Future<Output = Result<Self::Extract, Self::Error>> + Send;
fn filter(&self, internal: Internal) -> Self::Future;
fn map_err<F, E>(self, _internal: Internal, fun: F) -> MapErr<Self, F>
...
}
我不明白为什么添加的链接会引起and_then
方法的需求更改,因为对我来说,这里的泛型关系非常复杂.
Even with the hints provided by rust-analyzer, it doesn't help a lot, because the Extract = ...
part is eclipsed.