如何为 trait 实现多个类似的方法?

4

我正在实现Serde Serializer trait,其中有很多方法。其中许多看起来非常相似(例如那些整数类型的方法只是将字节复制到某个缓冲区),因此能够通过某种方式自动生成这些方法将是不错的选择。我是否可以编写一些通用函数或宏以一个方法(宏)实现许多方法?

我的实现如下:

use serde::Serializer;
use byteorder::{WriteBytesExt, LittleEndian};

struct MySerializer {
     ...
}

impl Serializer for MySerializer {
    fn serialize_i32(&mut self, v:i32) -> Result<(), Error> {
        try!(self.buffer.write_i32::<LittleEndian>(v));
    }
    fn serialize_u8(&mut self, v:u8) -> Result<(), Error> {
        try!(self.buffer.write_u8::<LittleEndian>(v));
    }
    // many similar looking functions here
}

Rust确实支持泛型编程:https://doc.rust-lang.org/book/generics.html - gbe
1
@gbe 当然,我知道它确实可以。但是我不仅需要泛型,我还需要使用新标识符(名称)生成新函数。我目前的理解是,不幸的是现在不可能做到这一点,因为 Rust 的宏规则不允许生成新的标识符。 - Pavel Davydov
1个回答

0

我在serde/bench项目中找到了一个示例:

macro_rules! impl_nums {
    ($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
        #[inline]
        fn $dser_method<V>(&mut self, mut visitor: V) -> Result<V::Value>
            where V: Visitor
        {
            let value = try!(self.reader.$reader_method::<NativeEndian>());
            visitor.$visitor_method(value)
        }
    };
}

impl_nums!(u16, deserialize_u16, visit_u16, read_u16);
impl_nums!(u32, deserialize_u32, visit_u32, read_u32);
....

目前看来这是最好的方法 - concat_idents! 宏不稳定,根据这个 Github 问题也不是很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接