Created
May 14, 2023 11:38
-
-
Save rbran/9feec2bf4bc42dfcc2e08b3220e6aafd to your computer and use it in GitHub Desktop.
Avoid using a blanket implementations by using Borrow instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::borrow::{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!"); | |
} | |
} | |
fn speak_to<S>(s: impl Borrow<S>) | |
where | |
S: Speaker, | |
{ | |
// borrow allow us to get a reference from lots of types, such: | |
// Box, Cow, Rc, Arc, &T, T, etc | |
let s: &S = s.borrow(); | |
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::<BasicSpeaker>(speaker_ref); | |
// Maybe take a refernce 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(); | |
speak_to::<BasicSpeaker>(speaker_cow); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment