Enjoy Day 5
We impl
(implement) some trait
(aka skill) for our struct
so it can have any desired skill.
trait, impl
You also can impl
any trait
for struct
👇.
// Just boring struct. #[derive(Debug, Clone)] struct Animal {} struct Human {} // New skill. Wanna to say something? trait Sayable { // This nearly like interface. fn say(&self) -> String; // We use String instead of &str here for no reason. } // Implement `Sayable` skill for `Animal`. impl Sayable for Animal { // All animal will say meow for now. 😆 fn say(&self) -> String { "meow!".to_owned() // convert &str to String. } } // Implement `Sayable` skill for `Human`. impl Sayable for Human { // All human kind say hi! 🤘 fn say(&self) -> String { "hi!".to_owned() // convert &str to String. } } fn main() { let animal = Animal {}; // So we can call like this. println!("{:?}", animal.say()); // Or this. println!("{:?}", Animal::say(&animal)); // Now human turn (with shorthand). println!("{:?}", Human::say(&Human {})); }
That's look like impl
to struct
, but this time we can implement that trait
to any struct
we want!
Take a way
trait
is a skill.impl
is how we implement skill.- So
impl Sayable for Animal
littery meanimplement sayable skill to animal
. 🐈💬
Async with Tokio
We will use tokio
crate for now.
Cargo.toml
[package]
name = "foo"
version = "0.1.0"
edition = "2021"
[dependencies]
async-trait = "0.1.59"
tokio = { version ="1.22", features = ["full"] }
main.rs
use std::thread::sleep; use std::time::{Duration, SystemTime}; async fn sleep_2secs() { // Will sleep for 2 seconds. sleep(Duration::new(2, 0)); } // This `async fn main` need `tokio::main`. #[tokio::main] async fn main() { // Wait for for 2 sec. let now = SystemTime::now(); sleep_2secs().await; // Ensure it's 2 sec. let now_sec = now.elapsed().ok().unwrap().as_secs(); assert_eq!(now_sec, 2); println!("We have been asleep for {} seconds.", now_sec); }
Async Traits
And let's use tokio
with trait
.
Cargo.toml
[package]
name = "foo"
version = "0.1.0"
edition = "2021"
[dependencies]
async-trait = "0.1.59"
tokio = { version ="1.22", features = ["full"] }
main.rs
use async_trait::async_trait; use std::thread::sleep; use std::time::{Duration, SystemTime}; // 👇 We need this. #[async_trait] trait Animal { // 👇 Because of this async. async fn sleep(&self); } struct Cat; // 👇 Also here. #[async_trait] impl Animal for Cat { async fn sleep(&self) { // Will sleep for 2 seconds. sleep(Duration::new(2, 0)); } } // This `async fn main` need `tokio::main`. #[tokio::main] async fn main() { // Wait for sleepy cat for 2 sec. let now = SystemTime::now(); Cat {}.sleep().await; // Ensure it's 2 sec. let now_sec = now.elapsed().ok().unwrap().as_secs(); assert_eq!(now_sec, 2); println!("Cat has been asleep for {} seconds.", now_sec); }
💡 We also have
async trait
supported byasync-trait
lib. Official support is almost there.