gpt4 book ai didi

rust - 使用泛型别名特征继承

转载 作者:行者123 更新时间:2023-11-29 08:21:30 26 4
gpt4 key购买 nike

我开始为一个新的库使用 Rust。我正在努力思考实现以下内容的可能方法。

接下来是更多的期望表达而不是真正的语法。我试图表达这一点的所有方式要么不编译,要么在我去实现其中一个别名特征时不编译。

struct ConcreteType;
struct CommonType;

trait Handler<Rin, Rout = Rin>{
fn handle_event(&self, msg: &Rin);
}

// alias Handler with one of the types defined as a common case
trait HandlerToMessage<M> : Handler <ConcreteType, M>{
fn handle_event(&self, msg: &ConcreteType) {
// default implementation of parent trait
// example is simplified, forget about how Rout/M is actually used
self.decode(msg)
}

// method to implement
fn decode(&self, msg: &ConcreteType) -> M;
}

// another alias for most common case where Rin/Rout are ConcreteType, CommonType most often
trait HandlerToCommonType : HandlerToMessage <ConcreteType, CommonType>{
fn decode(&self, msg: &ConcreteType) -> CommonType
{
...
};
}

使用关联类型的替代方法

trait Handler{
type Rin;
type Rout; // not yet able to do Rout = Rin with associated types

fn handle_event(&self, msg: &Self::Rin) -> Self::Rout;
}


trait HandlerToMessage : Handler <Rin=ConcreteType>{
fn handle_event(&self, msg: &Self::Rin) {
// common functionality
self.decode(msg)
}

// method to implement
fn decode(&self, msg: &Self::Rin) -> Self::Rout;
}

trait HandlerToCommonType : HandlerToMessage <Rout=CommonType>{

fn decode(&self, msg: &ConcreteType) -> CommonType
{
...
}
}

在 C++ 中,这大致是我想要完成的

// real world example I've seen in the wild of this structure
template <class Rout>
class Context {
public:
void dispatch(Rout* msg);
};

template <class Rin, Rout = Rin>
class ReadHandler {
public:
void read (Context* ctx, Rin* msg) = 0;

private:
Context<Rout> ctx_;
};

// very common to convert from a byte buffer some message type
template <class M>
class BytesToMessageDecoder : ReadHandler<IOBuffer, M> {
public:
// Template method pattern
void read (Context* ctx, IOBuffer* msg) {
M msgOut;
bool success;
success = this->decode(msg, &msgOut);
if (success) {
ctx->dispatch(msgOut);
}
}

bool decode(IOBuffer* msg, M* msgOut) = 0;

}

// convert one byte buffer to another is common
typedef BytesToMessageDecoder<IOBuffer> BytesToBytesDecoder;


// Concrete implementations
// look for fixed number of bytes incoming
class FixedLengthFrameDecoder : BytesToBytesDecoder {
bool decode(IOBuffer* msg, IOBuffer* msgOut) { ... }
}

// fields are prefixed with a length. Wait for that many bytes and then dispatch
class LengthBasedFieldDecoder: BytesToBytesDecoder {
bool decode(IOBuffer* msg, IOBuffer* msgOut) { ... }
}

class StringDecoder : BytesToMessageDecoder<std::string> {
// decode from byte buffer to a string
bool decode(IOBuffer* msg, std::string* msgOut) { ... }
}

基本上,顶级特征 Handler 是最通用的,但可能并不意味着除了高级库用户之外的任何人都可以实现。 HandlerToMessage trait 是一种常见的转换,我们将 ConcreteType 转换为其他类型。图书馆可以实现其中的几个。 HandlerToCommonType 是最常见的情况,许多库类型都希望从中开始。

Rout 如何在 Handler 特性中使用的细节并不重要。我试图简化示例并省略一些参数,希望能使我试图传达的内容更加简洁。我对此的所有搜索要么让我认为这是不可能传达的,要么我在滥用它。我不太明白这是否属于新的特化实现,但从我的理解来看并不像。

我意识到 Rust 不是 C++,所以我尝试做的可能不受支持或具有不同的语法。任何以正确语法或更惯用的 Rust 方式提供的帮助都将不胜感激。

最佳答案

也许你可以只拥有单独的特征并为另一个的所有实现者实现一个:

struct ConcreteType;
struct CommonType;

trait Handler<Input, Output = Input> {
fn handle_event(&self, msg: &Input) -> Output;
}

trait HandlerToMessage<M> {
fn decode(&self, msg: &ConcreteType) -> M;
}

impl<T, M> Handler<ConcreteType, M> for T
where T: HandlerToMessage<M>
{
fn handle_event(&self, msg: &ConcreteType) -> M {
self.decode(msg)
}
}

impl HandlerToMessage<CommonType> for () {
fn decode(&self, _msg: &ConcreteType) -> CommonType {
unimplemented!()
}
}

fn main() {}

最后一个真的很尴尬,因为您通常会为具体类型实现一个特征,但您并没有真正提出任何有意义的实现。

关于rust - 使用泛型别名特征继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37758080/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com