Skip to content

Instantly share code, notes, and snippets.

@rbran
Created May 14, 2023 11:46
Show Gist options
  • Save rbran/9892e957ce53ed78f933576523fd30c5 to your computer and use it in GitHub Desktop.
Save rbran/9892e957ce53ed78f933576523fd30c5 to your computer and use it in GitHub Desktop.
Avoid using a blanket implementations by forcing the user to provide a reference in the first place.
use std::borrow::Cow;
/// A trait for things that can speak.
trait Speaker {
fn speak(&self);
}
/// BasicSpeaker is an empty struct that exists only to implement Speaker.
#[derive(Clone)]
struct BasicSpeaker;
/// BasicSpeakers must be able to speak.
impl Speaker for BasicSpeaker {
fn speak(&self) {
println!("Hello!");
}
}
// just force a ref, after all the `Speaker::speak` uses a ref
fn speak_to(s: &impl Speaker) {
s.speak();
}
fn main() {
// Create a BasicSpeaker struct:
let speaker = BasicSpeaker;
speaker.speak();
speak_to(&speaker);
// Take a reference to the BasicSpeaker:
let speaker = BasicSpeaker;
let speaker_ref: &BasicSpeaker = &speaker;
speaker_ref.speak();
speak_to(speaker_ref);
// Take a mut ref to the BasicSpeaker:
let mut speaker = BasicSpeaker;
let speaker_mut_ref: &mut BasicSpeaker = &mut speaker;
speaker_mut_ref.speak();
speak_to(speaker_mut_ref); //rust convert this automatically for us
// Maybe take a ref to the BasicSpeaker, maybe own it.
let speaker = BasicSpeaker;
let speaker_cow = if std::env::args().len() == 1 {
Cow::Borrowed(&speaker)
} else {
Cow::Owned(speaker.clone())
};
speaker_cow.speak();
// owned or not, just get the reference for it.
speak_to(speaker_cow.as_ref());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment