Giới thiệu
Hello everyone, chúng ta tiếp tục học Go ngày 2 nhé. Let’s go!!!
Nội dung
Pointers
Pointer là một biến chứa địa chỉ của một vùng nhớ trong bộ nhớ. Thay vì lưu trực tiếp giá trị vào biến, ta có thể lưu trữ địa chỉ của giá trị đó và sử dụng con trỏ để truy cập đến giá trị đó. Việc sử dụng con trỏ trong Go có thể giúp cải thiện hiệu suất và tiết kiệm bộ nhớ so với việc sao chép dữ liệu giữa các biến.
Để tạo một con trỏ, bạn sử dụng toán tử “&” để lấy địa chỉ của một biến, và toán tử “*” để truy cập giá trị tại địa chỉ đó.
cú pháp:
- Toán tử “&”:123i <span class="token operator">:=</span> <span class="token number">42</span>p <span class="token operator">=</span> <span class="token operator">&</span>i
- Toán tử “*”:12g <span class="token operator">:=</span> <span class="token operator">*</span>p
Ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">import</span> <span class="token string">"fmt"</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> i<span class="token punctuation">,</span> j <span class="token operator">:=</span> <span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">2701</span> p <span class="token operator">:=</span> <span class="token operator">&</span>i <span class="token comment">// point trỏ tới địa chỉ ô nhớ của i</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token operator">*</span>p<span class="token punctuation">)</span> <span class="token comment">// kết quả => 42</span> <span class="token operator">*</span>p <span class="token operator">=</span> <span class="token number">21</span> <span class="token comment">// gán giá trị vào ô nhớ</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span> <span class="token comment">// kết quả => 21</span> p <span class="token operator">=</span> <span class="token operator">&</span>j <span class="token comment">// gán point trỏ tới địa chỉ ô nhớ của j</span> <span class="token operator">*</span>p <span class="token operator">=</span> <span class="token operator">*</span>p <span class="token operator">/</span> <span class="token number">37</span> <span class="token comment">// gán giá trị vào ô nhớ</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>j<span class="token punctuation">)</span> <span class="token comment">// kết quả => 73</span> <span class="token punctuation">}</span> |
Structs
Struct là một kiểu dữ liệu (composite data type) cho phép bạn định nghĩa một tập hợp các trường (fields) có kiểu dữ liệu khác nhau. Nó giúp bạn tổ chức và lưu trữ các dữ liệu có liên quan với nhau trong cùng một đối tượng.
1 2 3 4 5 6 7 8 9 | <span class="token keyword">type</span> Vertex <span class="token keyword">struct</span> <span class="token punctuation">{</span> X <span class="token builtin">int</span> Y <span class="token builtin">int</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>Vertex<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Chúng ta có thể tạo một đối tượng Vertex bằng cách gán giá trị cho các trường dữ liệu của struct.
1 2 3 4 5 | vertex <span class="token operator">:=</span> Vertex<span class="token punctuation">{</span> Y<span class="token punctuation">:</span> <span class="token number">100</span><span class="token punctuation">,</span> X<span class="token punctuation">:</span> <span class="token number">200</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> |
Chúng ta có thể truy cập và gán giá trị cho các trường dữ liệu của struct bằng cách sử dụng toán tử “.”.
1 2 3 | vertex<span class="token punctuation">.</span>Y <span class="token operator">=</span> <span class="token number">200</span> vertex<span class="token punctuation">.</span>X <span class="token operator">=</span> <span class="token number">300</span> |
Chúng ta có thể truy cập và sửa đổi nội dung của struct bằng cách sử dụng Pointer.
1 2 3 4 | v <span class="token operator">:=</span> Vertex<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">}</span> p <span class="token operator">:=</span> <span class="token operator">&</span>v p<span class="token punctuation">.</span>X <span class="token operator">=</span> <span class="token number">400</span> |
Arrays
Một mảng được khai báo bằng cách chỉ định loại dữ liệu được lưu trữ và độ dài của mảng.
Cú pháp:
1 2 | <span class="token keyword">var</span> <span class="token operator"><</span>name<span class="token operator">></span> <span class="token punctuation">[</span>lenght<span class="token punctuation">]</span><span class="token operator"><</span><span class="token keyword">type</span><span class="token operator">></span> |
ví dụ: Tạo mảng a có chiều dài là 10 với các phần tử kiểu int.
1 2 | <span class="token keyword">var</span> a <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token builtin">int</span> |
Lưu ý: Một khi khai báo, chiều dài và kiểu dữ liệu của mảng thì không thể thay đổi. Nếu muốn thay đổi chiều dài, phải tạo mảng mới và sao chép dữ liệu từ mảng cũ.
Zero value
Khi khai báo một mảng mà không gán giá trị, toàn bộ phần tử sẽ được gán giá trị mặc định theo kiểu dữ liệu (int = 0, string = “”).
Ví dụ: mảng [5]int sẽ có tất cả các phần tử có giá trị 0.
Literal
1 2 | array <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">}</span> |
Calculating Size
Nếu độ dài được cho là “…”, Go sẽ xác định độ dài của mảng dựa trên số phần tử được khởi tạo.
1 2 | array <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token operator">...</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">}</span> |
Specific elements
Nếu bạn biết độ dài của mảng mình cần, nhưng chỉ khởi tạo các phần tử cụ thể, bạn có thể sử dụng cú pháp này.
1 2 | array <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token punctuation">}</span> |
Pointer elements
Bạn có thể có một mảng các con trỏ. Bạn sử dụng toán tử * để truy cập giá trị mỗi con trỏ mà phần tử trỏ tới.
1 2 3 4 5 | array <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token function">new</span><span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">:</span> <span class="token function">new</span><span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">*</span>array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">10</span> <span class="token operator">*</span>array<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">20</span> |
Các giá trị của mảng được khai báo trong array trông giống như hình dưới đây:
Một mảng là một giá trị trong Go. Điều này có nghĩa là bạn có thể sử dụng nó trong một thao tác gán. Do đó, một mảng có thể được gán cho các mảng khác cùng loại và cùng độ dài.
1 2 3 4 | <span class="token keyword">var</span> array1 <span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token builtin">int</span> array2 <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">}</span> array1 <span class="token operator">=</span> array2 |
Còn đối với Pointer thì khi chúng ta gán là gán các địa chỉ ô nhớ của con trỏ chứ không phải các giá trị mà con trỏ đang trỏ tới.
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">var</span> array1 <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token builtin">string</span> array2 <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token function">new</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">new</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">new</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">*</span>array2<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Red"</span> <span class="token operator">*</span>array2<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Blue"</span> <span class="token operator">*</span>array2<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Green"</span> array1 <span class="token operator">=</span> array2 |
Nó trông giống như hình dưới đây:
Multidimensional array ( mảng đa chiều )
Multidimensional là một cấu trúc dữ liệu cho phép lưu trữ các phần tử dưới dạng bảng nhiều chiều. Mỗi phần tử trong mảng đa chiều được xác định bởi nhiều chỉ số được gọi là các chỉ mục.
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token comment">// initialize</span> <span class="token keyword">var</span> array <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token builtin">int</span> <span class="token comment">// literal & initialize</span> array <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">21</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">31</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">41</span><span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token comment">// Declare & initialize outer array</span> array <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">21</span><span class="token punctuation">}</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 number">40</span><span class="token punctuation">,</span> <span class="token number">41</span><span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token comment">// Declare & initialize outer and inner array</span> array <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token punctuation">}</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 number">1</span><span class="token punctuation">:</span> <span class="token number">41</span><span class="token punctuation">}</span><span class="token punctuation">}</span> |
Giống như hình dưới đây:
Passing arrays between functions
Khi truyền một mảng giữa các hàm, có thể tốn nhiều bộ nhớ và ảnh hưởng đến hiệu suất. Mảng được truyền bằng cách sao chép toàn bộ mảng vào hàm với bất kể kích thước nào của nó.
1 2 3 4 5 6 7 8 9 | <span class="token comment">// Khai báo 1 mảng 8 megabytes.</span> <span class="token keyword">var</span> num <span class="token punctuation">[</span><span class="token number">1e6</span><span class="token punctuation">]</span><span class="token builtin">int</span> <span class="token function">handleNum</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">handleNum</span><span class="token punctuation">(</span>num <span class="token punctuation">[</span><span class="token number">1e6</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> |
Khi gọi hàm handleNum với một mảng 8 megabytes, toàn bộ mảng sẽ được sao chép và cấp phát trên ngăn xếp, tốn nhiều bộ nhớ và ảnh hưởng đến hiệu suất. Cách tốt hơn là truyền một con trỏ đến mảng và để chỉ sao chép 8 byte.
1 2 3 4 5 6 7 8 | <span class="token keyword">var</span> num <span class="token punctuation">[</span><span class="token number">1e6</span><span class="token punctuation">]</span><span class="token builtin">int</span> <span class="token function">handleNum</span><span class="token punctuation">(</span><span class="token operator">&</span>num<span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">handleNum</span><span class="token punctuation">(</span>num <span class="token operator">*</span><span class="token punctuation">[</span><span class="token number">1e6</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> |
Tổng kết
Vậy là sau 1 ngày mình đã học được:
- Pointers
- Structs
- Arrays
Nếu có thắc mắc hoặc cần giải thích rõ thêm chỗ nào thì các bạn có thể comment ở dưới.
Cám ơn các bạn đã theo dõi bài viết của mình. Chúc các bạn có 1 ngày vui vẻ. Tks