DST (Dynamically Sized Types) are a thing in Rust now. I have used them successfully, with a flexible last member which is known to the compiler (such as [u8]
).
What I am looking to do, however, is to create a custom DST. Say, for example:
struct Known<S> {
dropit: fn (&mut S) -> (),
data: S,
}
struct Unknown {
dropit: fn (&mut ()) -> (),
data: (),
}
With an expected usage being Box<Known<S>>
=> Box<Unknown>
=> Box<Known<S>>
, where the middleware need not know about concrete types.
Note: yes, I know about Any
, and no I am not interested in using it.
I am open to suggestions in the layout of both Known
and Unknown
, however:
size_of::<Box<Known>>() = size_of::<Box<Unknown>>() = size_of::<Box<u32>>()
; that is it should be a thin pointer.- dropping
Box<Unknown>
drops its content - cloning
Box<Unknown>
(assuming a clonableS
), clones its content - ideally,
fn dup(u: &Unknown) -> Box<Unknown> { box u.clone() }
works
I have particular difficulties with (3) and (4), I could solve (3) with manually allocating memory (not using box
, but directly calling malloc
) but I would prefer providing an idiomatic experience to the user.
I could not find any documentation on how to inform box
of the right size to allocate.
unsafe
code, is probably the easiest, most reliable, and all around best option. It most likely won't fit into the existing DST scheme or into Box. – user395760[T]
), where it adds a length member; and trait objects (Trait
,Trait + Send
, &c.), where it adds a vtable including a destructor which knows how large an object to free. There is no mechanism for declaring your own variety of unsized objects. – Chris Morganbox
allocates based onstd::mem::size_of
? – Matthieu M.