मेरे पास एक विशेषता है जो एक संबद्ध प्रकार के deserializing के लिए एक फ़ंक्शन है। हालाँकि, उस संबद्ध प्रकार को आजीवन रहने की आवश्यकता होती है, जिसे कॉल करने वाला तय करता है, इसलिए मेरे पास एक अलग विशेषता है कि मैं उच्च श्रेणी के लिए बाध्य विशेषता का उपयोग करता हूं, ताकि यह किसी भी जीवनकाल के लिए निर्जन हो सके।
मुझे एक क्लोजर का उपयोग करने की आवश्यकता है जो इस संबद्ध प्रकार को वापस करता है।
मेरे पास ऐसा करने के लिए निम्नलिखित कोड है:
#![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
एक है MyEndpointBody
, जिसे मैं बंद करने से लौट रहा हूं, लेकिन रस्ट को नहीं लगता कि वे एक ही प्रकार हैं। मैं यह अनुमान लगा रहा हूं क्योंकि रस्ट MyEndpointBody
टाइप के लिए असंगत अनाम जीवनकाल उठाता है , लेकिन मुझे नहीं पता कि इसे कैसे ठीक किया जाए।
मुझे यह कोड काम करने के लिए कैसे मिल सकता है ताकि मैं HRTB से जुड़े प्रकार के साथ एक क्लोजर का उपयोग कर सकूं?
Fn
पैरामीटर को एक मनमाना जीवनकाल की आवश्यकता होती है। लेकिन यहाँ यह जीवनकाल निर्भर हो जाता है और यह इस तरह के उपयोग को असंभव बना देता है, कृपया देखें: play.rust-lang.org/…