Go cung cấp nhiều kiểu dữ liệu khác nhau nhằm đáp ứng nhu cập lập trình từ cơ bản đến phức tạp. Hiện tại Go cung cấp 4 nhóm kiểu dữ liệu khác nhau:
- Nhóm cơ bản: số (int, float, complex), chuỗi (string) và luận lý (boolean).
- Nhóm tập hợp: kết hợp các kiểu dữ liệu nhóm cơ bản tạo ra kiểu dữ liệu phức tạp hơn: mảng (array) và cấu trúc (struct).
- Nhóm tham chiếu: con trỏ (pointer), lát (slice), bản đồ (map), hàm (function) và kênh (channel). Đặc điểm chung của nhóm này là cùng tham chiếu đến một đối tượng hoặc trạng thái nên những xử lý tác động lên đối tượng mà nó tham chiếu thì các tham chiếu khác đến đối tượng đó đều biết được.
- Nhóm giao diện (interface): đây là kiểu dữ liệu thể hiện tổng quát hóa hay trừu tượng hóa về hành vi của các kiểu dữ liệu khác. Nó được dùng để đại diện cho các kiểu dữ liệu khác.
Số nguyên
Go cung cấp 4 loại số nguyên ứng với khả năng lưu trữ của nó là 8, 16, 32 hay 64 bit. Mỗi loại như vậy gồm 2 loại có dấu và không dấu nên tổng cộng có 8 kiểu dữ liệu thể hiện số nguyên:
- Số nguyên có dấu: int8, int16, int32 và int64. Phạm vi lưu trữ từ -2^n-1 đến 2^(n-1) - 1 với n là số bit lưu trữ. Ví dụ: int8: từ -128 (-2^7) đến 127 (2^7 - 1).
- Số nguyên không dấu: uint8, uint16, uint32 và uint64. Phạm vi lưu trữ từ 0 đến 2^n - 1. Ví dụ: uint8: từ 0 đến 255 (2^8 - 1).
Go cho phép chúng ta tự định nghĩa một kiểu dữ liệu mới hoàn toàn hoặc dựa trên kiểu cũ qua khai báo kiểu dữ liệu như có đề cập ở bài 4. Cú pháp như sau:
type <tên kiểu dữ liệu mới> <thông tin mô tả>
Dựa trên khai báo này, Go tự định nghĩa thêm 4 kiểu số nguyên mới là byte (=uint8), rune (=int32), uint và int. Byte thường dùng để mô tả mảng dữ liệu thô, chủ yếu liên quan đọc ghi dữ liệu. Rune được dùng để thể hiện giá trị 1 ký tự Unicode. Còn uint và int không có kích thước cố định, biến đổi theo kiến trúc 32 bit hay 64 bit. int thường được dùng cho số nguyên khi không quá quan tâm đến kích thước số nguyên cần lưu. Ngoài ra Go có cung cấp thêm 1 kiểu dữ liệu số nguyên là uintptr, thường dùng cho lập trình cấp thấp.
Go khá nghiêm ngặt về kiểu dữ liệu. Mặc dù cùng kiểu nguyên kích thước 1 byte nhưng byte và uint8 là khác nhau, không thể gán qua lại dễ dàng được. Sẽ nói rõ trong phần sau.
Go cung cấp các phép toán số học, phép toán bit, và so sánh cho các biến kiểu số nguyên chia làm 5 nhóm như sau:
* | / | % | << | >> | & | &^ |
+ | - | | | ^ | |||
== | != | < | <= | > | >= | |
&& | ||||||
|| |
- Nhóm 1 gồm nhân, chia, phép lấy số dư, phép dịch bit sang trái, phép dịch bit sang phải, phép và bit và phép xóa bit.
- Nhóm 2: gồm cộng, trừ, phép hoặc bit và phép hoặc loại trừ bit.
- Nhóm 3: gồm các phép so sánh bằng, khác, nhỏ hơn, nhỏ hơn hoặc bằng, lớn hơn, và lớn hơn hoặc bằng.
- Nhóm 4 và 5: phép và luận lý và phép hoặc luận lý. Hai phép này dùng để nối các biểu thức ở 3 nhóm trên trong các biểu thức điều kiện.
Các phép cùng nhóm thì thứ tự tính toán là như nhau nên sẽ tính từ trái qua trong một biểu thức. Tuy nhiên chúng ta nên dùng dấu ngoặc để phân tách cho rõ ràng, tránh nhầm lẫn. Nhóm trên có độ ưu tiên cao hơn nhóm dưới. Ví dụ: a + b*c | a - b%c thì thứ tự tương đương ((a + (b*c)) | a) - (b%c).
Kết quả biểu thức như trên thường dùng để so sánh hoặc lưu giữ vào một biến. Phép toán bằng = là cách thức để lưu giữ giá trị vào một biến. Ví dụ: x = a + b*c. Chúng ta đã thấy dấu = được sử dụng ở khai báo biến hoặc hằng. Ở đây, khi phép toán = được sử dụng để gán giá trị cho một biến đã được khai báo thì nếu giá trị gán không thuộc kiểu dữ liệu của biến đã khai báo, Go sẽ báo lỗi khi biên dịch. Ví dụ biến x ở trên kiểu int nhưng nếu kết quả phép toán ở trên là thập phân thì Go sẽ báo lỗi. Nếu kết quả gán vượt quá khả năng chứa của kiểu dữ liệu biến tương ứng, Go cũng sẽ báo lỗi.
Phép toán hai nhóm 1 và 2 ở trên được Go hỗ trợ cách rút ngắn khi thể hiện nếu kết quả được gán cho một biến trong phép toán. Ví dụ: muốn tăng giá trị của biến i lên 10, thông thường ta viết:
i = i + 10
thì Go hỗ trợ cách viết
i += 10
Tương tự muốn tăng i lên 10 lần, ta viết i *= 10. Khi muốn tăng hay giảm i 1 đơn vị, Go hỗ trợ cách viết gọn hơn nữa là i++ hoặc i--. Go cũng hỗ trợ cách viết +i và -i tương ứng 0 + i hoặc 0 - i. Lưu ý, Go không hỗ trợ ++i hay --i như C hay java.
Hai số nguyên cùng kiểu có thể so sánh với nhau như các phép so sánh nêu ở nhóm 3. Kết quả của phép so sánh là 1 giá trị thuộc kiểu luận lý mà ta sẽ tìm hiểu sau: đúng (true) hoặc sai (false).
Phép toán bit là phép toán thú vị mà chỉ áp dụng trên số nguyên:
- Phép và (AND) bit (&): cho kết quả từ so sánh từng bit của 2 số nguyên, bit có giá trị 1 nếu bit tương ứng ở cả 2 số đều bằng 1. Ví dụ: x = 69 & 89 thì giá trị của x sẽ là 65
Giá trị | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
69 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
89 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 |
69&89=65 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
- Phép hoặc(OR) bit (|): bit kết quả có giá trị 1 nếu bit tương ứng của ít nhất một trong hai giá trị là 1. Ví dụ: x = 69 | 89 thì giá trị của x sẽ là 93
Giá trị | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
69 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
89 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 |
69|89=93 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
- Phép hoặc loại trừ (XOR) bit (^): bit kết quả có giá trị 1 nếu bit tương ứng của hai giá trị là ngược nhau. Ví dụ: x = 69 ^ 89 thì giá trị của x sẽ là 28
Giá trị | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
69 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
89 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 |
69^89=28 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
- Phép xóa bit (&^): bit kết quả có giá trị 0 nếu bit tương ứng của giá trị vế sau là 1. Ngược lại nó sẽ nhận giá trị bit tương ứng của giá trị vế trước biểu thức. Ví dụ: x = 69 &^ 89 thì giá trị của x sẽ là 4
Giá trị | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
69 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
89 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 |
69&^89=4 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
- Phép dịch trái bit (<<): toàn bộ bit sẽ được dịch về bên trái ứng với số lượng nêu ở trong biểu thức. Các bit bị dịch nằm ngoài phạm vi lưu trữ của kiểu dữ liệu sẽ bị loại bỏ. Các bit trống sẽ có giá trị 0. Ví dụ: x = 15 << 2 thì x sẽ có giá trị là 60
Giá trị | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
15 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
15<<2=60 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 |
- Phép dịch phải bit (>>): toàn bộ bit sẽ được dịch về bên phải ứng với số lượng nêu ở trong biểu thức. Các bit bị dịch nằm ngoài phạm vi lưu trữ của kiểu dữ liệu sẽ bị loại bỏ. Các bit trống sẽ có giá trị 0. Ví dụ: x = 15 >> 2 thì x sẽ có giá trị là 3
Giá trị | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
15 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
15>>2=60 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
Nếu để ý sẽ thấy phép dịch trái tương đương nhân với 2^n (2 lũy thừa n) với n là số bit dịch. Ngược lại dịch phải sẽ tương ứng với chia cho 2^n. Phép dịch trái và phải chỉ áp dụng với số nguyên dương.
Bài tiếp theo chúng ta sẽ tiếp tục bàn về hai kiểu dữ liệu số khác là số dấu chấm động (số thực) và số phức và kiểu dữ liệu luận lý.
Tóm tắt:
- Go chia 4 nhóm kiểu dữ liệu:
+ Cơ bản: int, float, complex, string và boolean.
+ Tập hợp: array và struct
+ Tham chiếu: pointer, slice, map, function và channel.
+ Interface.
- Kiểu int: int8, int16, int32, int64, uint8, uint16, uint32, uint64, byte, rune và int.
- 5 nhóm toán tử với các phép số học (+,-,8,/,%), phép toán bit(&,|,^,&^, <<,>>), phép so sánh (==, !=, <, <=, >, >=) và phép toán luận lý (&&, ||).
No comments:
Post a Comment