Skip to content

Instantly share code, notes, and snippets.

@kyleheadley kyleheadley/as_trait.rs
Last active Apr 1, 2018

Embed
What would you like to do?
Demonstration of casting to multiple trait objects
use std::thread;
use std::sync::Arc;
use std::sync::RwLock;
struct Wrap{one:usize,zero:usize}
trait WriteIt {
fn write1(&mut self,w:usize);
fn read1(&self) -> usize;
}
impl WriteIt for Wrap {
fn write1(&mut self,w:usize) { self.zero = w; }
fn read1(&self) -> usize { self.zero }
}
impl<B:WriteIt+?Sized> WriteIt for Arc<RwLock<B>> {
fn write1(&mut self,w:usize) { self.write().unwrap().write1(w) }
fn read1(&self) -> usize { self.read().unwrap().read1() }
}
trait ReadIt {
fn read2(&self) -> usize;
}
impl ReadIt for Wrap {
fn read2(&self) -> usize { self.zero }
}
impl<A:ReadIt+?Sized> ReadIt for Arc<RwLock<A>> {
fn read2(&self) -> usize { self.read().unwrap().read2() }
}
fn main() {
let a = Arc::new(RwLock::new(Wrap{zero:56,one:1}));
let mut b = a.clone() as Arc<RwLock<WriteIt+Send+Sync>>;
let c = a.clone() as Arc<RwLock<ReadIt+Send+Sync>>;
// let c = b.clone() as Arc<RwLock<ReadIt+Send+Sync>>; // error, non-primitive cast
println!("a: {}, b: {}, c: {}",a.read1(),b.read1(),c.read2());
// a: 5, b: 5, c: 5
*a.write().unwrap() = Wrap{zero:9,one:7};
// *b.write().unwrap() = 9; // error, can't assign to trait object
println!("a: {}, b: {}, c: {}",a.read1(),b.read1(),c.read2());
// a: 9, b: 9, c: 9
thread::spawn(move||{
println!("b: {}, c: {}",b.read1(),c.read2());
// b: 9, c: 9
b.write1(8);
println!("b: {}, c: {}",b.read1(),c.read2());
// b: 8, c: 8
// let _bb = b.write().unwrap();
// println!("c: {}",c.read2());
// panic! already mutably borrowed
});
thread::sleep(std::time::Duration::from_millis(50));
println!("a: {}",a.read1());
// a: 8
let a0 = a.read().unwrap().zero;
let a1 = a.read().unwrap().one;
println!("a.zero: {}, a.one: {}",a0,a1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.