관련 형식을 deserialize하는 기능이있는 특성이 있습니다. 그러나 관련 유형에는 발신자가 결정한 수명이 필요하므로 상위 특성을 사용하는 별도의 특성이 있으므로 평생 동안 직렬화를 해제 할 수 있습니다.
이 관련 유형을 반환하는 클로저를 사용해야합니다.
이를 수행하기 위해 다음 코드가 있습니다.
#![allow(unreachable_code)]
use std::marker::PhantomData;
trait Endpoint: for<'a> EndpointBody<'a> {}
trait EndpointBody<'a> {
type Out: 'a;
fn serialize(body: &Self::Out) -> Vec<u8>;
fn deserialize(raw_body: &'a [u8]) -> Self::Out;
}
// /////////////////////////////////////////////////////////
/// Trait object compatible handler
trait Handler {
fn execute(&self, raw_body: &[u8]) -> Vec<u8>;
}
/// Wraps a function for an endpoint, convertint it to a Handler
struct FnHandler<EP, F>
where
EP: Endpoint,
F: 'static + for<'a> Fn(&'a [u8]) -> <EP as EndpointBody<'a>>::Out,
{
func: F,
_ph: PhantomData<EP>,
}
impl<EP, F> FnHandler<EP, F>
where
EP: Endpoint,
F: 'static + for<'a> Fn(&'a [u8]) -> <EP as EndpointBody<'a>>::Out,
{
pub fn new(func: F) -> Self {
Self {
func,
_ph: PhantomData,
}
}
}
impl<EP, F> Handler for FnHandler<EP, F>
where
EP: Endpoint,
F: 'static + for<'a> Fn(&'a [u8]) -> <EP as EndpointBody<'a>>::Out,
{
fn execute(&self, in_raw_body: &[u8]) -> Vec<u8> {
let body = (self.func)(in_raw_body);
let serialized_body = unimplemented!();
return serialized_body;
}
}
// /////////////////////////////////////////////////////////
/// Collection of handlers
struct Handlers(Vec<Box<dyn Handler>>);
impl Handlers {
pub fn new() -> Self {
Self(vec![])
}
pub fn handle<EP: 'static, F>(&mut self, func: F)
where
EP: Endpoint,
F: 'static + for<'a> Fn(&'a [u8]) -> <EP as EndpointBody<'a>>::Out,
{
self.0.push(Box::new(FnHandler::<EP, F>::new(func)));
}
}
// /////////////////////////////////////////////////////////
struct MyEndpoint;
struct MyEndpointBody<'a> {
pub string: &'a str,
}
impl Endpoint for MyEndpoint {}
impl<'a> EndpointBody<'a> for MyEndpoint {
type Out = MyEndpointBody<'a>;
fn serialize(body: &Self::Out) -> Vec<u8> {
unimplemented!()
}
fn deserialize(raw_body: &'a [u8]) -> Self::Out {
unimplemented!()
}
}
// /////////////////////////////////////////////////////////
fn main() {
let mut handlers = Handlers::new();
handlers.handle::<MyEndpoint, _>(|_body| MyEndpointBody {
string: "test string",
});
handlers.0[1].execute(&[]);
}
나는 그것이 작동해야한다고 생각하지만, 확인하면 유형 오류가 발생합니다.
error[E0271]: type mismatch resolving `for<'a> <[closure@src/main.rs:92:38: 94:6] as std::ops::FnOnce<(&'a [u8],)>>::Output == <MyEndpoint as EndpointBody<'a>>::Out`
--> src/main.rs:92:14
|
92 | handlers.handle::<MyEndpoint, _>(|_body| MyEndpointBody {
| ^^^^^^ expected struct `MyEndpointBody`, found associated type
|
= note: expected struct `MyEndpointBody<'_>`
found associated type `<MyEndpoint as EndpointBody<'_>>::Out`
= note: consider constraining the associated type `<MyEndpoint as EndpointBody<'_>>::Out` to `MyEndpointBody<'_>`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
때문에 혼란 MyEndpoint::Out
A는 MyEndpointBody
내가 폐쇄에서 복귀하고있는, 그러나 녹들은 같은 종류 생각하지 않습니다. Rust가 MyEndpointBody
유형에 대해 호환되지 않는 익명의 수명을 선택했기 때문에 추측 하지만 그 해결 방법을 모르겠습니다.
HRTB 관련 유형으로 클로저를 사용할 수 있도록이 코드를 작동 시키려면 어떻게해야합니까?
Fn
의 매개 변수는 임의의 수명을 가져야 하므로 일반화 된 솔루션이 아닐 수 있습니다 . 그러나 여기에서이 수명은 의존적이되어 사용이 불가능 해집니다. play.rust-lang.org/…