Movatterモバイル変換


[0]ホーム

URL:


core::clone

TraitCloneToUninit

Source
pub unsafe trait CloneToUninit {    // Required method    unsafe fnclone_to_uninit(&self, dest:*mutu8);}
🔬This is a nightly-only experimental API. (clone_to_uninit #126799)
Expand description

A generalization ofClone todynamically-sized types stored in arbitrary containers.

This trait is implemented for all types implementingClone,slices of allsuch types, and other dynamically-sized types in the standard library.You may also implement this trait to enable cloning custom DSTs(structures containing dynamically-sized fields), or use it as a supertrait to enablecloning atrait object.

This trait is normally used via operations on container types which support DSTs,so you should not typically need to call.clone_to_uninit() explicitly except whenimplementing such a container or otherwise performing explicit management of an allocation,or when implementingCloneToUninit itself.

§Safety

Implementations must ensure that when.clone_to_uninit(dest) returns normally rather thanpanicking, it always leaves*dest initialized as a valid value of typeSelf.

§Examples

If you are defining a trait, you can addCloneToUninit as a supertrait to enable cloning ofdyn values of your trait:

#![feature(clone_to_uninit)]usestd::rc::Rc;traitFoo: std::fmt::Debug + std::clone::CloneToUninit {fnmodify(&mutself);fnvalue(&self) -> i32;}implFoofori32 {fnmodify(&mutself) {*self*=10;    }fnvalue(&self) -> i32 {*self}}letfirst: Rc<dynFoo> = Rc::new(1234);letmutsecond = first.clone();Rc::make_mut(&mutsecond).modify();// make_mut() will call clone_to_uninit()assert_eq!(first.value(),1234);assert_eq!(second.value(),12340);

The following is an example of implementingCloneToUninit for a custom DST.(It is essentially a limited form of whatderive(CloneToUninit) would do,if such a derive macro existed.)

#![feature(clone_to_uninit)]usestd::clone::CloneToUninit;usestd::mem::offset_of;usestd::rc::Rc;#[derive(PartialEq)]structMyDst<T:?Sized> {    label: String,    contents: T,}unsafe impl<T:?Sized + CloneToUninit> CloneToUninitforMyDst<T> {unsafe fnclone_to_uninit(&self, dest:*mutu8) {// The offset of `self.contents` is dynamic because it depends on the alignment of T        // which can be dynamic (if `T = dyn SomeTrait`). Therefore, we have to obtain it        // dynamically by examining `self`, rather than using `offset_of!`.        //        // SAFETY: `self` by definition points somewhere before `&self.contents` in the same        // allocation.letoffset_of_contents =unsafe{            (&rawconstself.contents).byte_offset_from_unsigned(self)        };// Clone the *sized* fields of `self` (just one, in this example).        // (By cloning this first and storing it temporarily in a local variable, we avoid        // leaking it in case of any panic, using the ordinary automatic cleanup of local        // variables. Such a leak would be sound, but undesirable.)letlabel =self.label.clone();// SAFETY: The caller must provide a `dest` such that these field offsets are valid        // to write to.unsafe{// Clone the unsized field directly from `self` to `dest`.self.contents.clone_to_uninit(dest.add(offset_of_contents));// Now write all the sized fields.            //            // Note that we only do this once all of the clone() and clone_to_uninit() calls            // have completed, and therefore we know that there are no more possible panics;            // this ensures no memory leaks in case of panic.dest.add(offset_of!(Self, label)).cast::<String>().write(label);        }// All fields of the struct have been initialized; therefore, the struct is initialized,        // and we have satisfied our `unsafe impl CloneToUninit` obligations.}}fnmain() {// Construct MyDst<[u8; 4]>, then coerce to MyDst<[u8]>.letfirst: Rc<MyDst<[u8]>> = Rc::new(MyDst {        label: String::from("hello"),        contents: [1,2,3,4],    });letmutsecond = first.clone();// make_mut() will call clone_to_uninit().foreleminRc::make_mut(&mutsecond).contents.iter_mut() {*elem*=10;    }assert_eq!(first.contents, [1,2,3,4]);assert_eq!(second.contents, [10,20,30,40]);assert_eq!(second.label,"hello");}

§See Also

  • Clone::clone_from is a safe function which may be used instead whenSelf: Sizedand the destination is already initialized; it may be able to reuse allocations owned bythe destination, whereasclone_to_uninit cannot, since its destination is assumed to beuninitialized.
  • ToOwned, which allocates a new destination container.

Required Methods§

Source

unsafe fnclone_to_uninit(&self, dest:*mutu8)

🔬This is a nightly-only experimental API. (clone_to_uninit #126799)

Performs copy-assignment fromself todest.

This is analogous tostd::ptr::write(dest.cast(), self.clone()),except thatSelf may be a dynamically-sized type (!Sized).

Before this function is called,dest may point to uninitialized memory.After this function is called,dest will point to initialized memory; it will besound to create a&Self reference from the pointer with thepointer metadatafromself.

§Safety

Behavior is undefined if any of the following conditions are violated:

  • dest must bevalid for writes forsize_of_val(self) bytes.
  • dest must be properly aligned toalign_of_val(self).
§Panics

This function may panic. (For example, it might panic if memory allocation for a cloneof a value owned byself fails.)If the call panics, then*dest should be treated as uninitialized memory; it must not beread or dropped, because even if it was previously valid, it may have been partiallyoverwritten.

The caller may wish to take care to deallocate the allocation pointed to bydest,if applicable, to avoid a memory leak (but this is not a requirement).

Implementors should avoid leaking values by, upon unwinding, dropping all component valuesthat might have already been created. (For example, if a[Foo] of length 3 is beingcloned, and the second of the three calls toFoo::clone() unwinds, then the firstFoocloned should be dropped.)

Implementors§

Source§

implCloneToUninit forstr

Source§

implCloneToUninit forByteStr

Source§

implCloneToUninit forCStr

Source§

impl<T:Clone>CloneToUninit for[T]

Source§

impl<T:Clone>CloneToUninit for T


[8]ページ先頭

©2009-2025 Movatter.jp