
- The copy trait is used for types that do not manage heap memory (e.g., integer types).
- The clone trait is essential for types that allocate memory on the heap or hold other resources, ensuring each copy has its own independent allocation.

Practical Examples
Consider the following examples to understand the difference between copying and cloning in Rust. The typei32 implements the Copy trait, so its value is automatically copied during assignments. On the other hand, a String requires an explicit call to clone to create an independent copy.
x (of type i32) is effortlessly copied, allowing both x and y to be used independently. For the String type, invoking s1.clone() explicitly creates an independent duplicate, ensuring that both s1 and s2 point to different heap allocations.
When you create a string using String::from, memory is allocated on the heap. The string consists of a pointer, its length, and its capacity. Invoking clone on a string allocates new memory and copies the content from the original string. Thus, the new string, s2, has its own pointer, length, and capacity.
