Trait bounds in Rust are really powerful and also offers lots of idiomatic ways to constrain your model. Bounds are for enforcing constraints even in other languages like Scala, but Rust offers them at a different level.
Here's one example from the book Rust for Rustaceans (a great book BTW).
Suppose you want to construct a HashMap<K, V, S>
, whose keys are some generic type T
, value is a usize
, you can write bounds like T: Hash + Eq
, S: BuildHasher + Default
.
pub fn doit<T>(value: T)
where T: Hash + Eq {
let mut h = HashMap::new();
h.insert(value, 10usize);
}
But if you want to constrain your user to just use .collect
and from_iter()
on the HashMap
, you can just write HashMap<T, usize, S>: FromIterator
. With this bound, you want your user to be able to create the collection only from an iterator. Trying to use any other method like .insert()
will give compilation error.
pub fn doit_again<T>(value: T)
where HashMap<T, usize>: FromIterator<(T, usize)> {
// `insert` will not be allowed by the compiler
// let h: HashMap<T, usize>= HashMap::new();
// h.insert(value, 10usize);
let iter = [(value, 10_usize)];
let h = HashMap::from_iter(iter);
}
By constraining the bound, you make your model intent more explicit and clear.
I don't know much about Scala which has
+
,-
,<:
... If Rust doesn't have them, how can it cover the use cases where they are used? If you can give Scala examples where+
,-
,<:
... are used, and then convert them to Rust, that'll be great :-)