anyerr 上下文中的类型体操
在对 Rust 错误处理的思考和 anyerr一文中,我介绍了 anyerr 这一个错误处理库,其可以携带上下文信息,且储存上下文的数据结构是可定制的。本文则聚焦 anyerr 是如何实现这样的特性的。 上下文的核心特性 基本结构和表示 在设计之前,首先我们要明确需求。什么样的上下文数据结构是我们所需要的?携带上下文是为了能够记录某些变量所保存的值,我们需要记录变量的名称和其中的值。上下文可以有很多种类,但所有的上下文都可以表示为一个键值映射表。 所以以下是我们对一个上下文储存的基本特性的定义: pub trait AbstractContext: Default + Debug + Send + Sync + 'static { type Key; type Value; type Entry: Entry<Key = Self::Key, Value = Self::Value>; type Iter<'a>: Iter<'a, Entry = Self::Entry> where Self: 'a; fn iter(&self) -> Self::Iter<'_>; } 这样的一个 trait 定义仅仅规定了一个上下文的键值对类型和迭代其中元素的方法,却没有插入或者其他查询的方法。这是因为一个上下文不一定需要真的携带有信息,如果不需要上下文,那么一个不带有任何信息的上下文就可以非常好地适用于这种场景,这也是为什么这个 trait 叫做 AbstractContext。anyerr 针对这样的情况有特殊的优化,这些后面再说。 上下文的元素 AbstractContext::Entry 规定了上下文中每一个元素的类型,其应当实现 Entry trait。以下则是 Entry 的定义: pub trait Entry: Debug + Send + Sync + 'static { type Key: Borrow<Self::KeyBorrowed> + Debug + Send + Sync + 'static; type KeyBorrowed: Debug + Display + Eq + Hash + ?...