I want to transfer a trait object from a Box
into another container, like Arc
.
use std::sync::Arc;
trait MyTrait {}
struct MyStruct {}
impl MyTrait for MyStruct {}
fn main() {
// works as expected
let dynamic: Arc<dyn MyTrait> = Arc::new(MyStruct{}) as Arc<dyn MyTrait>;
// error
let my_box: Box<dyn MyTrait> = Box::new(MyStruct{});
let dynamic: Arc<dyn MyTrait> = Arc::new(*my_box) as Arc<dyn MyTrait>;
}
This give me:
error[E0277]: the size for values of type `dyn MyTrait` cannot be known at compilation time
Sounds pretty simple to me but I cannot figure out how to do this.
You can't, try and keep unsized things in the smart pointer they will end up in. Once we get something like unsized-locals we can do this.
This has to do with the fact that Box
has a different layout than Arc
or Rc
so you can't just copy over the data.
1 Like
Ok, thanks.
In my case this would be Arc<RwLock<dyn MyTrait>>
that I'd have to pass around, which is pretty unergonomic
Is there an RFC I could follow?
Here's the tracking issue for unsized rvlaues
https://github.com/rust-lang/rust/issues/48055
2 Likes
You can create a wrapper type that works based off of closures callbacks if that makes it more bearable.
Thank you, but I think the longish type name adds less complexity in my case. It might help others, though.
1 Like
For moving a trait object from Box to Arc, are you maybe looking for Arc::from?
use std::sync::Arc;
trait MyTrait {}
struct MyStruct;
impl MyTrait for MyStruct {}
fn main() {
let b: Box<dyn MyTrait> = Box::new(MyStruct);
let a: Arc<dyn MyTrait> = Arc::from(b);
}
8 Likes
Yes, this would work for (some?) pointer-like types. Arc
was an example. My actual type is Arc<RwLock<T>>
and RwLock<T>
doesn't implement From<Box<T>>
.
But thanks for pointing out that there are some types where this works.
Then you can't, because the representaion of Arc<RwLock<T>>
is too different from Box<T>
to do a conversion.
system
Closed
August 25, 2019, 6:39pm
10
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.