What programming language does not have Struct
.
Struct
is similar to Tuple
, but differs in one place: Struct
accesses data by field name, and Tuple
is equal to index.
Defining a Struct
and declaring an instance of that Struct
is as simple as this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token attribute attr-name">#[derive(Debug)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span> active <span class="token punctuation">:</span> <span class="token keyword">bool</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token keyword">u64</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someone@example.com"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someusername123"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> active <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> user1 <span class="token punctuation">.</span> email <span class="token operator">=</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"anotheremail@example.com"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{}"</span> <span class="token punctuation">,</span> user1 <span class="token punctuation">.</span> email <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:?}"</span> <span class="token punctuation">,</span> user1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> user1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Result:
1 2 3 4 5 6 7 8 9 | anotheremail@example.com User <span class="token punctuation">{</span> active: true, username: <span class="token string">"someusername123"</span> , email: <span class="token string">"anotheremail@example.com"</span> , sign_in_count: <span class="token number">1</span> <span class="token punctuation">}</span> User <span class="token punctuation">{</span> active: true, username: <span class="token string">"someusername123"</span> , email: <span class="token string">"anotheremail@example.com"</span> , sign_in_count: <span class="token number">1</span> , <span class="token punctuation">}</span> |
Reading the code should be easy to understand, here, just note that a Struct
that wants to print to the screen with println!()
must have #[derive(Debug)]
at the top and print using the println!("{:?}", user1)
or println!("{:#?}", user1)
Ownership with Structure
Ok, now I will test the properties of Ownership
for User
, looking at User
has 2 fields, username
and email
of type String
, as I said in the previous post, a Struct
that in its component contains type String
or Vector
, the value will be stored on the Heap
, I don’t know if it will be saved in the type of active
sign_in_count
stored on the Stack
, email
username
stored on the Heap
or saved all active
sign_in_count
username
email
on the Heap
, but that’s it. There is also no need to think carefully, because the behavior of the User
in these two cases is the same.
Consider for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token attribute attr-name">#[derive(Debug)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span> active <span class="token punctuation">:</span> <span class="token keyword">bool</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token keyword">u64</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someone@example.com"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someusername123"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> active <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> user2 <span class="token operator">=</span> user1 <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> user1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// ERROR</span> <span class="token punctuation">}</span> |
Since the value of user1
is stored on the Heap
, when assigning let user2 = user1
the ownership
of that value has been transferred from user1
to user2
so println!("{:#?}", user1);
will error.
If we can’t assign it, we use clone
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #[derive(Debug, Clone)] struct User { active: bool, username: String, email: String, sign_in_count: u64, } fn main() { let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; let user2 = user1.clone(); println!("{:#?}", user1); println!("{:#?}", user2); } |
Result
1 2 3 4 5 6 7 8 9 10 11 12 13 | User <span class="token punctuation">{</span> active: true, username: <span class="token string">"someusername123"</span> , email: <span class="token string">"someone@example.com"</span> , sign_in_count: <span class="token number">1</span> , <span class="token punctuation">}</span> User <span class="token punctuation">{</span> active: true, username: <span class="token string">"someusername123"</span> , email: <span class="token string">"someone@example.com"</span> , sign_in_count: <span class="token number">1</span> , <span class="token punctuation">}</span> |
Note: a
Struct
that wants to useclone
must declare#[derive(Clone)]
for thatStruct
Let’s look at an example with a simple struct containing only fields of known data types:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token attribute attr-name">#[derive(Debug, Clone, Copy)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Location</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token keyword">i32</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token keyword">i32</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token class-name">Location</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> a <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> a <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> b <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Easy to understand, because Location
only contains 2 value fields stored on the Stack
, so the assignment does not affect the ownership
, only a Struct
who wants to perform the assignment must declare #[derive(Clone, Copy)]
, Note that having Copy
is a must have Clone
, having Clone
is not necessarily having Copy
, if there is Copy
without Clone
, the following error will be displayed when compiling:
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token number">383</span> <span class="token operator">|</span> pub trait Copy: Clone <span class="token punctuation">{</span> <span class="token operator">|</span> ^^^^^ required by this bound <span class="token keyword">in</span> <span class="token variable"><span class="token variable">`</span> Copy <span class="token variable">`</span></span> <span class="token operator">=</span> note: this error originates <span class="token keyword">in</span> the derive macro <span class="token variable"><span class="token variable">`</span> Copy <span class="token variable">`</span></span> <span class="token punctuation">(</span> in Nightly builds, run with -Z macro-backtrace <span class="token keyword">for</span> <span class="token function">more</span> info <span class="token punctuation">)</span> help: consider annotating <span class="token variable"><span class="token variable">`</span> Location <span class="token variable">`</span></span> with <span class="token variable"><span class="token variable">`</span> <span class="token comment">#[derive(Clone)]</span> <span class="token variable">`</span></span> <span class="token operator">|</span> <span class="token number">10</span> <span class="token operator">|</span> <span class="token comment">#[derive(Clone)]</span> <span class="token operator">|</span> error: aborting due to previous error For <span class="token function">more</span> information about this error, try <span class="token variable"><span class="token variable">`</span> rustc --explain E0277 <span class="token variable">`</span></span> <span class="token builtin class-name">.</span> |
So if you want Location
to behave like User
, how to do it, simply remove Copy
, now the assignment will change ownership
, if you want to clone()
, you must have Clone
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token attribute attr-name">#[derive(Debug, Clone)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> rect1 <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token number">30</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> rect2 <span class="token operator">=</span> rect1 <span class="token punctuation">.</span> <span class="token function">clone</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> rect3 <span class="token operator">=</span> rect2 <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> rect1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> rect2 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// ERRO</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> rect3 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
So why don’t we add Copy
for the User
struct above so that it can be assigned without affecting ownership
, forbidden, Rust strictly forbids adding Copy
to any struct that has at least 1 field with a data type of zero size. known in advance – the value stored on the Heap
.
Create an instance from another instance
Here are the ways to create, the code is also easy to understand:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <span class="token attribute attr-name">#[derive(Debug, Clone)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span> active <span class="token punctuation">:</span> <span class="token keyword">bool</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token keyword">u64</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someone@example.com"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someusername123"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> active <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> active <span class="token punctuation">:</span> user1 <span class="token punctuation">.</span> active <span class="token punctuation">,</span> username <span class="token punctuation">:</span> user1 <span class="token punctuation">.</span> username <span class="token punctuation">.</span> <span class="token function">clone</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> email <span class="token punctuation">:</span> user1 <span class="token punctuation">.</span> email <span class="token punctuation">.</span> <span class="token function">clone</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> user1 <span class="token punctuation">.</span> sign_in_count <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> user1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> user2 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <span class="token attribute attr-name">#[derive(Debug)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">User</span> <span class="token punctuation">{</span> active <span class="token punctuation">:</span> <span class="token keyword">bool</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token keyword">u64</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// --snip--</span> <span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someone@example.com"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"someusername123"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> active <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> sign_in_count <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> email <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"another@example.com"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> username <span class="token punctuation">:</span> <span class="token class-name">String</span> <span class="token punctuation">::</span> <span class="token function">from</span> <span class="token punctuation">(</span> <span class="token string">"anotheruser"</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">..</span> user1 <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> user1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> user2 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Unit-like structure
We can define a struct with no fields:
1 2 3 4 5 6 | <span class="token keyword">struct</span> <span class="token type-definition class-name">AlwaysEqual</span> <span class="token punctuation">;</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> subject <span class="token operator">=</span> <span class="token class-name">AlwaysEqual</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Methods and Associated Functions
The definition of accociated functions
is as simple as this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token attribute attr-name">#[derive(Debug)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">impl</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> <span class="token keyword">fn</span> <span class="token function-definition function">square</span> <span class="token punctuation">(</span> size <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token keyword">Self</span> <span class="token punctuation">{</span> <span class="token keyword">Self</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> size <span class="token punctuation">,</span> height <span class="token punctuation">:</span> size <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> sq <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">::</span> <span class="token function">square</span> <span class="token punctuation">(</span> <span class="token number">3</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
It’s also easy to understand how to define and use ha.
The method definition is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <span class="token attribute attr-name">#[derive(Debug)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">impl</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> <span class="token keyword">fn</span> <span class="token function-definition function">area</span> <span class="token punctuation">(</span> <span class="token operator">&</span> <span class="token keyword">self</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token keyword">u32</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> width <span class="token operator">*</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> height <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">can_hold</span> <span class="token punctuation">(</span> <span class="token operator">&</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> other <span class="token punctuation">:</span> <span class="token operator">&</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token keyword">bool</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> width <span class="token operator">></span> other <span class="token punctuation">.</span> width <span class="token operator">&&</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> height <span class="token operator">></span> other <span class="token punctuation">.</span> height <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> rect1 <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token number">30</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> rect2 <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">40</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> rect3 <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token number">60</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">45</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"Can rect1 hold rect2? {}"</span> <span class="token punctuation">,</span> rect1 <span class="token punctuation">.</span> <span class="token function">can_hold</span> <span class="token punctuation">(</span> <span class="token operator">&</span> rect2 <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"Can rect1 hold rect3? {}"</span> <span class="token punctuation">,</span> rect1 <span class="token punctuation">.</span> <span class="token function">can_hold</span> <span class="token punctuation">(</span> <span class="token operator">&</span> rect3 <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Also split into 2 impl
as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <span class="token attribute attr-name">#[derive(Debug)]</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">impl</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> <span class="token keyword">fn</span> <span class="token function-definition function">area</span> <span class="token punctuation">(</span> <span class="token operator">&</span> <span class="token keyword">self</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token keyword">u32</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> width <span class="token operator">*</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> height <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">impl</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> <span class="token keyword">fn</span> <span class="token function-definition function">can_hold</span> <span class="token punctuation">(</span> <span class="token operator">&</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> other <span class="token punctuation">:</span> <span class="token operator">&</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token keyword">bool</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> width <span class="token operator">></span> other <span class="token punctuation">.</span> width <span class="token operator">&&</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> height <span class="token operator">></span> other <span class="token punctuation">.</span> height <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> rect1 <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token number">30</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> rect2 <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">40</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> rect3 <span class="token operator">=</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> width <span class="token punctuation">:</span> <span class="token number">60</span> <span class="token punctuation">,</span> height <span class="token punctuation">:</span> <span class="token number">45</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"Can rect1 hold rect2? {}"</span> <span class="token punctuation">,</span> rect1 <span class="token punctuation">.</span> <span class="token function">can_hold</span> <span class="token punctuation">(</span> <span class="token operator">&</span> rect2 <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"Can rect1 hold rect3? {}"</span> <span class="token punctuation">,</span> rect1 <span class="token punctuation">.</span> <span class="token function">can_hold</span> <span class="token punctuation">(</span> <span class="token operator">&</span> rect3 <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> rect1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> rect2 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">println!</span> <span class="token punctuation">(</span> <span class="token string">"{:#?}"</span> <span class="token punctuation">,</span> rect3 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Looks simple enough to understand, just notice that here we are not declaring Copy
for Rectangle
, so it is imperative that the functions in impl Retangle
we have to use reference &
to ensure ownership
for the variables.
Because Rectangle
only has 2 fields of data type i32
, we can declare Copy
for it, now the functions in impl Retangle
do not need to use reference &
anymore and still preserve the ownership
of the variables.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #[derive(Debug, Clone, Copy)] struct Rectangle { width: u32, height: u32, } impl Rectangle { fn area(self) -> u32 { self.width * self.height } } impl Rectangle { fn can_hold(self, other: Rectangle) -> bool { self.width > other.width && self.height > other.height } } fn main() { let rect1 = Rectangle { width: 30, height: 50, }; let rect2 = Rectangle { width: 10, height: 40, }; let rect3 = Rectangle { width: 60, height: 45, }; println!("Can rect1 hold rect2? {}", rect1.can_hold(rect2)); println!("Can rect1 hold rect3? {}", rect1.can_hold(rect3)); println!("{:#?}", rect1); println!("{:#?}", rect2); println!("{:#?}", rect3); } |