【问题标题】:How to implement many similar methods for trait?如何为 trait 实现许多类似的方法?
【发布时间】:2016-10-26 21:03:09
【问题描述】:

我正在实现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 是否支持泛型编程:doc.rust-lang.org/book/generics.html
  • @gbe 当然,我知道确实如此。但是,我不仅需要泛型,还需要生成具有新标识符(名称)的新函数。我目前的理解是,不幸的是,现在这是不可能的,因为 rust 的宏规则不允许生成新的 idents..

标签: generics rust serde


【解决方案1】:

我在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! 宏不稳定,根据this github issue,它不是很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    相关资源
    最近更新 更多