archery
is a rust library that offers a way to abstraction over
Rc
and
Arc
smart pointers.
This allows you to create data structures where the pointer type is parameterizable, so you can
avoid the overhead of Arc
when you don’t need to share data across threads.
In languages that supports
higher-kinded polymorphism
this would be simple to achieve without any library, but
rust does not support that yet.
To mimic higher-kinded polymorphism archery
implements the approach suggested by
Joshua Liebow-Feeser in
“Rust has higher kinded types already… sort of”.
While other approaches exist, they seem to always offer poor
ergonomics for the user.
To use archery
add the following to your Cargo.toml
:
[dependencies]
archery = "<version>"
archery
defines a SharedPointer
that receives the kind of pointer
as a type parameter. This gives you a convenient and ergonomic way to abstract the pointer
type away.
Declare a data structure with the pointer kind as a type parameter bounded by
SharedPointerKind
:
use archery::*;
struct KeyValuePair<K, V, P: SharedPointerKind> {
pub key: SharedPointer<K, P>,
pub value: SharedPointer<V, P>,
}
impl<K, V, P: SharedPointerKind> KeyValuePair<K, V, P> {
fn new(key: K, value: V) -> KeyValuePair<K, V, P> {
KeyValuePair {
key: SharedPointer::new(key),
value: SharedPointer::new(value),
}
}
}
To use it just plug-in the kind of pointer you want:
let pair: KeyValuePair<_, _, RcK> =
KeyValuePair::new("António Variações", 1944);
assert_eq!(*pair.value, 1944);
You can also use triomphe::Arc
as the backing implementation of a SharedPointer
.
This is generally faster than std::sync::Arc
.
Read triomphe
’s crate documentation to learn more
about it.
To use it you need to enable the triomphe
feature in archery
. Use ArcTK
as the pointer
kind in SharedPointer
.
We support serialization through serde. To use it
enable the serde
feature. To do so change the archery dependency in your Cargo.toml
to
[dependencies]
archery = { version = "<version>", features = ["serde"] }
Currently it is not possible to have unsized types inside a
SharedPointer
. As a workaround you can put the
unsized type inside a Box
.
An alternative to the approach taken by archery
is to use traits with associated types to encode
type-level functions. This has been suggested
multiple
times,
but offers ugly ergonomics (see
here
and here).