52 个版本 (9 个破坏性更新)

0.10.4 2024 年 8 月 13 日
0.10.3 2024 年 5 月 19 日
0.10.1 2024 年 4 月 16 日
0.9.7 2024 年 3 月 30 日
0.2.5 2023 年 11 月 27 日

#2397Rust 模式

Download history 5/week @ 2024-04-29 213/week @ 2024-05-06 145/week @ 2024-05-13 81/week @ 2024-05-20 21/week @ 2024-05-27 13/week @ 2024-06-03 395/week @ 2024-07-29 122/week @ 2024-08-12

每月 517 次下载
2 crates 中使用

MIT 许可证

190KB
3.5K SLoC

typle

typle crate 允许将泛型参数约束为元组,并支持操作元组组件。

例如,定义一个函数将一对元组压缩成一个元组的对

#[typle(Tuple for 0..=12)]
pub fn zip<A: Tuple, B: Tuple>(
    a: A,
    b: B,
) -> typle_for!(i in .. => (A<{i}>, B<{i}>))
{
    typle_for!(i in .. => (a[[i]], b[[i]]))
}

类型 AB 是泛型的,但被约束为元组。元组可以包含 0 到 12 个任何(大小)类型的组件,但两个元组必须具有相同的长度。

typle_for! 会遍历一个索引,返回一个具有指定组件的新元组。对于函数返回类型,它创建一个类型元组:((A<0>, B<0>), (A<1>, B<1>),...)。在函数体中,它创建一个值元组:((a.0, b.0), (a.1, b.1),...)

assert_eq!(
    zip(("LHR", "FCO", "ZRH"), (51.5, 41.8, 47.5)),
    (("LHR", 51.5), ("FCO", 41.8), ("ZRH", 47.5))
);
assert_eq!(
    zip((2.0, "test"), (Some(9u8), ('a', 'b'))),
    ((2.0, Some(9u8)), ("test", ('a', 'b')))
);
assert_eq!(
    zip((), ()),
    ()
);

typle 的一个常见用途是实现多个长度的元组的 trait。与使用声明性宏相比,typle 代码看起来更像 Rust,并提供对单个组件及其位置的访问。

例如,元组的 Hash 实现只是按顺序对元组的每个组件进行哈希。

使用 typle 这可以写成

#[typle(Tuple for 1..=12)]
impl<T> Hash for T
where
    T: Tuple,  // `T` must be a tuple with 1-12 components.
    T<_>: Hash,  // Each component must implement `Hash`.
    T<{T::LEN - 1}>: ?Sized,  // The last component may be unsized.
{
    #[inline]
    fn hash<S: Hasher>(&self, state: &mut S) {
        for typle_index!(i) in 0..T::LEN {
            self[[i]].hash(state);
        }
    }
}

与标准库中的当前实现进行比较

macro_rules! impl_hash_tuple {
    ( $($name:ident)+) => (
        impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
            #[allow(non_snake_case)]
            #[inline]
            fn hash<S: Hasher>(&self, state: &mut S) {
                let ($(ref $name,)+) = *self;
                $($name.hash(state);)+
            }
        }
    );
}

macro_rules! last_type {
    ($a:ident,) => { $a };
    ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
}

impl_hash_tuple! { T }
impl_hash_tuple! { T B }
impl_hash_tuple! { T B C }
impl_hash_tuple! { T B C D }
impl_hash_tuple! { T B C D E }
impl_hash_tuple! { T B C D E F }
impl_hash_tuple! { T B C D E F G }
impl_hash_tuple! { T B C D E F G H }
impl_hash_tuple! { T B C D E F G H I }
impl_hash_tuple! { T B C D E F G H I J }
impl_hash_tuple! { T B C D E F G H I J K }
impl_hash_tuple! { T B C D E F G H I J K L }

查看更多示例,请参阅crate 文档

依赖项

~275–720KB
~17K SLoC