Rust has a standard way to deal with default values of a type via Default trait. Read through its official docs to understand the design.
It can be auto-derived, but only for a struct whose all members have Default implementations. It is implemented for a great many types in the standard library, and also used in a surprising number of places. So if your type has a value that can be construed as being "default", it is a good idea to implement this trait.
If you're not satisfied with std deriving capabilities for Default, consider using smart-default crate. An example is quite self-explanatory:
#[derive(SmartDefault)]
enum Foo {
Bar,
#[default]
Baz {
#[default = 12]
a: i32,
b: i32,
#[default(Some(Default::default()))]
c: Option<i32>,
#[default(_code = "vec![1, 2, 3]")]
d: Vec<u32>,
#[default = "four"]
e: String,
},
Qux(i32),
}A great thing that having a Default implementation you can instantiate your struct with only the non-default values and have all other fields filled with default values:
let x = Foo { bar: baz, ..Default::default() };By default, all types in Rust follow 'move semantics'.
If you need a duplicate of a value, then its type should implement Clone trait (see official docs), and a duplicate is created by calling Clone methods explicitly. Cloning can be either cheap or expensive operation depending on type semantics.
However, Copy marker trait (see official docs) enables 'copy semantics' for a type, so a value is copied implicitly every time is passed. That's why copying must always perform a simple bit-to-bit copy operation.
Official Copy docs are quite explanatory about which types should be Copy and which types cannot:
Some types can't be copied safely. For example, copying
&mut Twould create an aliased mutable reference. CopyingStringwould duplicate responsibility for managing theString's buffer, leading to a double free.Generalizing the latter case, any type implementing
Dropcan't beCopy, because it's managing some resource besides its ownsize_of::<T>bytes.
Generally speaking, if your type can implement
Copy, it should. Keep in mind, though, that implementingCopyis part of the public API of your type. If the type might become non-Copyin the future, it could be prudent to omit theCopyimplementation now, to avoid a breaking API change.
For better understanding the topic, read through:
Estimated time: 1 day
- Create a
Pointtype which represents a 2D point (xandycoordinates). This type has to beCopyandDefault. - Create a
Polylinetype which represents a non-empty collection(whichever you want) ofPoints of unknown size. This type has to beCloneand non-Default.- Polyline must implement basic collection methods: addition of an item, removal of an item, getting an item. You may add additional methods & features if you desire.
After completing everything above, you should be able to answer (and understand why) the following questions: