问题
After reading about trait aliases, I tried to switch this code:
pub fn authorize<LoadClient>(get_client: LoadClient) -> Result<String, ()>
where
LoadClient: FnOnce(String) -> Result<Client, LoadingError>,
{
unimplemented!()
}
to
#![feature(trait_alias)]
trait LoadClient = FnOnce(String) -> Result<Client, ClientLoadingError>;
pub fn authorize(get_client: LoadClient) -> Result<String, ()> {
unimplemented!()
}
This gives me an error:
warning: trait objects without an explicit `dyn` are deprecated
--> src/oauth2/mod.rs:396:21
|
396 | get_client: LoadClient,
| ^^^^^^^^^^ help: use `dyn`: `dyn LoadClient`
|
= note: `#[warn(bare_trait_objects)]` on by default
error[E0277]: the size for values of type `(dyn std::ops::FnOnce(std::string::String) -> std::result::Result<oauth2::Client, oauth2::ClientLoadingError> + 'static)` cannot be known at compilation time
--> src/oauth2/mod.rs:396:9
|
396 | get_client: LoadClient,
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
Is it possible to use a trait alias in this way? This function is used elsewhere so it would be nice to have a shared definition rather than redefine it at each place it's used.
This is related to Can match on Result here be replaced with map_err and "?"
回答1:
You still need to use it as generic parameter:
#![feature(trait_alias)]
pub trait LoadClient = FnOnce(String) -> Result<Client, ClientLoadingError>;
pub fn authorize<T>(get_client: T) -> Result<String, ()>
where
T: LoadClient,
{
unimplemented!()
}
You also need to make the trait alias public since it is part of a public interface.
回答2:
It seems this was just a naive mistake related to using traits as arguments, rather than anything specific to trait aliases. I need to use impl LoadClient as described in the rust book when using traits as function parameters.
With the signature
pub fn authorize(get_client: impl LoadClient) -> Result<String, ()>
the code compiles.
来源:https://stackoverflow.com/questions/59720444/replacing-a-trait-bound-with-a-trait-alias-says-the-size-for-values-cannot-be-k