From 2af6f3b4aecf2f7372719c4cfd5525822a52edcd Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Tue, 17 Jan 2017 19:55:55 -0500 Subject: [PATCH] Add concrete wrapper trait draft --- _drafts/rust-concrete-wrapper-trait.md | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 _drafts/rust-concrete-wrapper-trait.md diff --git a/_drafts/rust-concrete-wrapper-trait.md b/_drafts/rust-concrete-wrapper-trait.md new file mode 100644 index 0000000..60e2b53 --- /dev/null +++ b/_drafts/rust-concrete-wrapper-trait.md @@ -0,0 +1,60 @@ +--- +title: "Rust: Creating Trait Objects for Traits with Generic Methods" +--- + +One of the rules +for being able to create [trait objects] +in Rust +is that the trait +cannot have any generic methods. + +For instance, +the [`Sample`] trait from `rand` +contains a generic `sample` method. + + pub trait Sample { + fn sample(&mut self, rng: &mut R) -> Support; + } + +If we want to do dynamic dispatch +on this trait, +we might have something +like this... + + struct Sampler { + sample: Box>, + } + +...which won't work. + + error[E0038]: the trait `rand::distributions::Sample` cannot be made into an object + --> src/main.rs:6:5 + | + 6 | sample: Box>, + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `rand::distributions::Sample` cannot be made into an object + | + = note: method `sample` has generic type parameters + +This makes sense, +since in order to build a trait object, +the compiler needs to populate a [vtable] +with function pointers +to the code for each method. +With generic methods, +the code doesn't even exist +unless it is called with a concrete type. + +Fortunately, +if we know the concrete type +we will be passing to `sample`, +we can create a wrapper trait. + + + use rand::ThreadRng; + trait ThreadRngSample { + fn thread_rng_sample(&mut self, rng: &mut ThreadRng) -> Support; + } + +[trait objects]: https://doc.rust-lang.org/book/trait-objects.html +[`Sample`]: https://docs.rs/rand/0.3.15/rand/distributions/trait.Sample.html +[vtable]: https://en.wikipedia.org/wiki/Virtual_method_table