1. Introduction
With Rust, generics is a concept born to avoid code duplication when dealing with a logic for many different data types. It still sounds a bit vague. We’ll go into more detail soon.
The example below is quite easy to understand, we will find the largest value in an array of integers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <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> number_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token number">25</span> <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">,</span> <span class="token number">65</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> largest <span class="token operator">=</span> <span class="token operator">&</span> number_list <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> number <span class="token keyword">in</span> <span class="token operator">&</span> number_list <span class="token punctuation">{</span> <span class="token keyword">if</span> number <span class="token operator">></span> largest <span class="token punctuation">{</span> largest <span class="token operator">=</span> number <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">"The largest number is {}"</span> <span class="token punctuation">,</span> largest <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">assert_eq!</span> <span class="token punctuation">(</span> <span class="token operator">*</span> largest <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
In the second example, we find the maximum value of two arrays and print them. The code still runs correctly but the loop logic to find the maximum value is repeated, looking very cumbersome.
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 | <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> number_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token number">25</span> <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">,</span> <span class="token number">65</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> largest <span class="token operator">=</span> <span class="token operator">&</span> number_list <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> number <span class="token keyword">in</span> <span class="token operator">&</span> number_list <span class="token punctuation">{</span> <span class="token keyword">if</span> number <span class="token operator">></span> largest <span class="token punctuation">{</span> largest <span class="token operator">=</span> number <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">"The largest number is {}"</span> <span class="token punctuation">,</span> largest <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> number_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token number">102</span> <span class="token punctuation">,</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">6000</span> <span class="token punctuation">,</span> <span class="token number">89</span> <span class="token punctuation">,</span> <span class="token number">54</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">43</span> <span class="token punctuation">,</span> <span class="token number">8</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> largest <span class="token operator">=</span> <span class="token operator">&</span> number_list <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> number <span class="token keyword">in</span> <span class="token operator">&</span> number_list <span class="token punctuation">{</span> <span class="token keyword">if</span> number <span class="token operator">></span> largest <span class="token punctuation">{</span> largest <span class="token operator">=</span> number <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">"The largest number is {}"</span> <span class="token punctuation">,</span> largest <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
In the third example, we’ll move the max value logic into a separate function and call it back when necessary.
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 | <span class="token keyword">fn</span> <span class="token function-definition function">largest</span> <span class="token punctuation">(</span> list <span class="token punctuation">:</span> <span class="token operator">&</span> <span class="token punctuation">[</span> <span class="token keyword">i32</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token operator">&</span> <span class="token keyword">i32</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> largest <span class="token operator">=</span> <span class="token operator">&</span> list <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> item <span class="token keyword">in</span> list <span class="token punctuation">{</span> <span class="token keyword">if</span> item <span class="token operator">></span> largest <span class="token punctuation">{</span> largest <span class="token operator">=</span> item <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> largest <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> number_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token number">25</span> <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">,</span> <span class="token number">65</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">largest</span> <span class="token punctuation">(</span> <span class="token operator">&</span> number_list <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">"The largest number is {}"</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">assert_eq!</span> <span class="token punctuation">(</span> <span class="token operator">*</span> result <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> number_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token number">102</span> <span class="token punctuation">,</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">6000</span> <span class="token punctuation">,</span> <span class="token number">89</span> <span class="token punctuation">,</span> <span class="token number">54</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">43</span> <span class="token punctuation">,</span> <span class="token number">8</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">largest</span> <span class="token punctuation">(</span> <span class="token operator">&</span> number_list <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">"The largest number is {}"</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">assert_eq!</span> <span class="token punctuation">(</span> <span class="token operator">*</span> result <span class="token punctuation">,</span> <span class="token number">6000</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Through the above 3 examples, the code has gradually become more compact and optimized through the following steps:
- Identify duplicate code
- Put duplicate codes into a separate function and specify input parameters and return values.
- Replace the duplicate logic with a function call.
What if the largest function we use is not only for data type i32 but also other data types such as char, float, … We will write more functions with input parameters of data types to be processed. . But it seems that the code logic is duplicated a lot This is when we need to use generics
2. Generic Data Types
Generic with function
In the example below, we want to find the largest character in an array of characters. Although the logic is the same as how to find the largest value in an array of integers, the input value in the largest_32
function before must be of type i32
. We had to create a new function, largest_char
. It’s time we use generics to optimize our code!
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 40 | <span class="token keyword">fn</span> <span class="token function-definition function">largest_i32</span> <span class="token punctuation">(</span> list <span class="token punctuation">:</span> <span class="token operator">&</span> <span class="token punctuation">[</span> <span class="token keyword">i32</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token operator">&</span> <span class="token keyword">i32</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> largest <span class="token operator">=</span> <span class="token operator">&</span> list <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> item <span class="token keyword">in</span> list <span class="token punctuation">{</span> <span class="token keyword">if</span> item <span class="token operator">></span> largest <span class="token punctuation">{</span> largest <span class="token operator">=</span> item <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> largest <span class="token punctuation">}</span> <span class="token keyword">fn</span> <span class="token function-definition function">largest_char</span> <span class="token punctuation">(</span> list <span class="token punctuation">:</span> <span class="token operator">&</span> <span class="token punctuation">[</span> <span class="token keyword">char</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token operator">&</span> <span class="token keyword">char</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> largest <span class="token operator">=</span> <span class="token operator">&</span> list <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> item <span class="token keyword">in</span> list <span class="token punctuation">{</span> <span class="token keyword">if</span> item <span class="token operator">></span> largest <span class="token punctuation">{</span> largest <span class="token operator">=</span> item <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> largest <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> number_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token number">25</span> <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">,</span> <span class="token number">65</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">largest_i32</span> <span class="token punctuation">(</span> <span class="token operator">&</span> number_list <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">"The largest number is {}"</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">assert_eq!</span> <span class="token punctuation">(</span> <span class="token operator">*</span> result <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> char_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token char string">'y'</span> <span class="token punctuation">,</span> <span class="token char string">'m'</span> <span class="token punctuation">,</span> <span class="token char string">'a'</span> <span class="token punctuation">,</span> <span class="token char string">'q'</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">largest_char</span> <span class="token punctuation">(</span> <span class="token operator">&</span> char_list <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">"The largest char is {}"</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token macro property">assert_eq!</span> <span class="token punctuation">(</span> <span class="token operator">*</span> result <span class="token punctuation">,</span> <span class="token char string">'y'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// The largest number is 100</span> <span class="token comment">// The largest char is y</span> |
The syntax when using generics to define the largest
function will be as follows:
1 2 3 4 | <span class="token keyword">fn</span> <span class="token function-definition function">largest</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token punctuation">(</span> list <span class="token punctuation">:</span> <span class="token operator">&</span> <span class="token punctuation">[</span> <span class="token class-name">T</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token operator">&</span> <span class="token class-name">T</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> |
T is a generic definition parameter for the data type to which the largest
function is passed. T stands for type , we can use other characters like U, A, B, C, Y, Z … , but usually the default choice is conventionally T.
When using the T parameter ta, it should be declared immediately after the function name by including a <> so that the compiler understands that you are using generics with the parameter T .
The largest
function after using generics will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token keyword">fn</span> <span class="token function-definition function">largest</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token punctuation">(</span> list <span class="token punctuation">:</span> <span class="token operator">&</span> <span class="token punctuation">[</span> <span class="token class-name">T</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token operator">&</span> <span class="token class-name">T</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token keyword">mut</span> largest <span class="token operator">=</span> <span class="token operator">&</span> list <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> item <span class="token keyword">in</span> list <span class="token punctuation">{</span> <span class="token keyword">if</span> item <span class="token operator">></span> largest <span class="token punctuation">{</span> largest <span class="token operator">=</span> item <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> largest <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> number_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token number">34</span> <span class="token punctuation">,</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token number">25</span> <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">,</span> <span class="token number">65</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">largest</span> <span class="token punctuation">(</span> <span class="token operator">&</span> number_list <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">"The largest number is {}"</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> char_list <span class="token operator">=</span> <span class="token macro property">vec!</span> <span class="token punctuation">[</span> <span class="token char string">'y'</span> <span class="token punctuation">,</span> <span class="token char string">'m'</span> <span class="token punctuation">,</span> <span class="token char string">'a'</span> <span class="token punctuation">,</span> <span class="token char string">'q'</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">largest</span> <span class="token punctuation">(</span> <span class="token operator">&</span> char_list <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">"The largest char is {}"</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Generic with struct
We can also use generics with structs, let’s take a look at the following examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token comment">// Định kiểu <T> ngay sau tên của struct</span> <span class="token comment">// x và y đều có kiểu dữ liệu là T</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Point</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token class-name">T</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token class-name">T</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> integer <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token comment">// x, y là số nguyên</span> <span class="token keyword">let</span> float <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">1.0</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">4.0</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token comment">// x,y là số thập phân</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">struct</span> <span class="token type-definition class-name">Point</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token class-name">T</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token class-name">T</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">// x,y được định có cùng kiểu T. Ở đây x là số nguyên còn y là số thập phân => Lỗi</span> <span class="token keyword">let</span> wont_work <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">4.0</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* | let wont_work = Point { x: 5, y: 4.0 }; | ^^^ expected integer, found floating-point number */</span> |
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token comment">// Ở đây ta định nghĩa với trình biên dịch 2 kiểu là T và U.</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Point</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token punctuation">,</span> <span class="token class-name">U</span> <span class="token operator">></span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token class-name">T</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token class-name">U</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> both_integer <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token comment">// T và U có thể giống nhau</span> <span class="token keyword">let</span> both_float <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">1.0</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">4.0</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">let</span> integer_and_float <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">4.0</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token comment">// T, U khác nhau</span> <span class="token punctuation">}</span> |
Generic with enum
1 2 3 4 5 6 7 8 | <span class="token attribute attr-name">#![allow(unused)]</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">enum</span> <span class="token type-definition class-name">Option</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token class-name">Some</span> <span class="token punctuation">(</span> <span class="token class-name">T</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token class-name">None</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 | <span class="token attribute attr-name">#![allow(unused)]</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">enum</span> <span class="token type-definition class-name">Result</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token punctuation">,</span> <span class="token class-name">E</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token class-name">Ok</span> <span class="token punctuation">(</span> <span class="token class-name">T</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token class-name">Err</span> <span class="token punctuation">(</span> <span class="token class-name">E</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Generic with methods
We can use generics for implementing methods of struct or enum.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token keyword">struct</span> <span class="token type-definition class-name">Point</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token class-name">T</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token class-name">T</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">impl</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token class-name">Point</span> <span class="token operator"><</span> <span class="token class-name">T</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token comment">// trả về tham chiếu kiểu T</span> <span class="token keyword">fn</span> <span class="token function-definition function">x</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 operator">&</span> <span class="token class-name">T</span> <span class="token punctuation">{</span> <span class="token operator">&</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> x <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> p <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">10</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">"p.x = {}"</span> <span class="token punctuation">,</span> p <span class="token punctuation">.</span> <span class="token function">x</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// p.x = 5</span> <span class="token punctuation">}</span> |
Note that we must declare T right after impl to be able to use T on Point <T>
type and not always the generic parameter type defined in the struct will be the same as in the method of the struct.
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 | <span class="token comment">// Định nghĩa struct Point với 2 kiểu dữ liệu X1, Y1</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Point</span> <span class="token operator"><</span> <span class="token constant">X1</span> <span class="token punctuation">,</span> <span class="token constant">Y1</span> <span class="token operator">></span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token constant">X1</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token constant">Y1</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">impl</span> <span class="token operator"><</span> <span class="token constant">X1</span> <span class="token punctuation">,</span> <span class="token constant">Y1</span> <span class="token operator">></span> <span class="token class-name">Point</span> <span class="token operator"><</span> <span class="token constant">X1</span> <span class="token punctuation">,</span> <span class="token constant">Y1</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token comment">// method mixup định nghĩa thêm X2, Y2. Vậy là ở đây chúng ta có 4 kiểu tham số **generic**</span> <span class="token keyword">fn</span> <span class="token function-definition function">mixup</span> <span class="token operator"><</span> <span class="token constant">X2</span> <span class="token punctuation">,</span> <span class="token constant">Y2</span> <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token keyword">self</span> <span class="token punctuation">,</span> other <span class="token punctuation">:</span> <span class="token class-name">Point</span> <span class="token operator"><</span> <span class="token constant">X2</span> <span class="token punctuation">,</span> <span class="token constant">Y2</span> <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token class-name">Point</span> <span class="token operator"><</span> <span class="token constant">X1</span> <span class="token punctuation">,</span> <span class="token constant">Y2</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> x <span class="token punctuation">,</span> <span class="token comment">// kiểu X1</span> y <span class="token punctuation">:</span> other <span class="token punctuation">.</span> y <span class="token punctuation">,</span> <span class="token comment">// kiểu Y2</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> p1 <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token number">10.4</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token comment">// X1: i32, Y1: f64</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span> x <span class="token punctuation">:</span> <span class="token string">"Hello"</span> <span class="token punctuation">,</span> y <span class="token punctuation">:</span> <span class="token char string">'c'</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token comment">// X2: str, Y2: char</span> <span class="token keyword">let</span> p3 <span class="token operator">=</span> p1 <span class="token punctuation">.</span> <span class="token function">mixup</span> <span class="token punctuation">(</span> p2 <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">"p3.x = {}, p3.y = {}"</span> <span class="token punctuation">,</span> p3 <span class="token punctuation">.</span> x <span class="token punctuation">,</span> p3 <span class="token punctuation">.</span> y <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// p3.x = 5, p3.y = c</span> <span class="token punctuation">}</span> |
Additional note : Using generics does not affect program performance compared to using specific data types.