Lập trình

Kiểu dữ liệu - Types

Ở chương trước, chúng ta đã sử dụng kiểu dữ liệu string để lưu trữ chuỗi Hello World. Kiểu dữ liệu phân loại một bộ dữ liệu liên quan, mô tả các phép tính (operation) có thể thực hiện được trên chúng và định nghĩa cách thức lưu trữ. Vì kiểu dữ liệu là một ý tưởng khá khó, vì vậy chúng ta sẽ đi qua vài ví dụ cụ thể trước khi xem xét đi chúng được triểu khai trong Go như thế nào.

Các nhà triết học thường phân biệt giữ các "khuôn mẫu" (type) và các biểu hiện (token). Ví dụ như bạn có một con chó tên là Max. Max là một biểu hiện (token) (là một thực thể hoặc một thành viên) và chó là một khuôn mẫu (type) (một khái niệm chung). "Chó" hay "Tính chó" mô tả một loạt các thuộc tính của tất cả các con chó đều có. Mặc dù quá đơn giản, chúng ta có thể thấy lý do như thế này: Tất cả các con chó có 4 chân. Max là một con chó, vì thế Max có 4 chân. Kiểu dữ liệu trong ngôn ngữ lập trình tương tự như vậy: Tất cả strings đều có độ dài, x là string, vì thế x có độ dài.

Trong toán học, chúng ta thường hay nói về tập hợp (sets). Ví dụ: ℝ (là một tập hợp số thực) hoặc ℕ (là một tập hợp số nguyên). Mỗi thành viên của các bộ này có chung thuộc tính với những thành viên khác của tập hợp. Ví dụ tất cả các số tự nhiên có tính liên kết: "Tất cả các số tự nguyên a, b, c, thì a+(b+c)=(a+b)+c và (a×b)×c=a×(b×c).". Nói như vầy, thì tập hợp tương tự như kiểu dữ liệu trong ngôn ngữ lập trình, vì tất cả các giá trị của cùng một loại kiểu dữ liệu có chung thuộc tính nhất định.

Go là một ngôn ngữ lập trình kiểu dữ liệu tĩnh (static type). Điều này có nghĩa là các biến được chỉ định rõ kiểu dữ liệu và kiểu dữ liệu đó không thể thay đổi. Kiểu dữ liệu tĩnh lúc đầu trông có vẻ là một trở ngại. Bạn sẽ phải tốn khá nhiều thời gian chỉ để sửa chương trình của bạn để có thể compile được. Nhưng kiểu dữ liệu sẽ giúp chúng ta suy đoán và bắt được một loạt các lỗi phổ biến.

Go đi kèm với nhiều loại kiểu dữ liệu tích hợp, bây giờ chúng ta sẽ xem xét chi tiết hơn.

Numbers

Go có nhiều kiểu dữ liệu để trình bày các con số. Nhìn chung chúng ta chia các con số thành 2 loại: số nguyên (integer) và số thực (số chấm động) (floating-point).

Integers

Integers - giống như bản sao bên toán học - là các con số không có thành phần thập phân. (...,-3,-2,-1,0,1...) Không giống như hệ đếm số 10 như chúng ta biểu diễn các con số. Máy tính sử dụng hệ nhị phân để biểu diễn.

Hệ thống đếm số của chúng ta được tạo ra từ 10 con sô khác nhau. Khi sử dụng hết lần lượt 1 con số trong 10 con số này, chúng ta tăng lên 2 con số rồi 3, 4, 5,... con số. Ví dụ sau số 9 là số 10, sau số 99 là sô 100 và cứ tiếp tục như vậy. Máy tính cũng làm tương tự, nhưng chúng chỉ có 2 con số mà thôi. Vì vậy chúng cách máy tính đếm như sau: 0, 1, 10, 11, 100, 110, 111 và cứ tiếp tục như vậy. Sự khác biệt giữa hệ thống số chúng ta sử dụng và máy tính sử dụng là các số nguyên có kích thước xác định. Bởi vì chúng có số lượng số nhất định. Ví dụ như interget 4bit sẽ trông như thế này: 0000, 0001, 0010, 0011, 0100. Và cuối cùng khi hết các vị trí, hầu hết máy tính sẽ quay về như khi bắt đầu. (Điều này dẫn đến một vài hành vi bất thường ở máy tính).

Kiểu dữ liệu integer trong Go gồm có: uint8, uint16, uint32, uint64, int8, int16, int32 and int64. Các con số 8, 16, 32 và 64 nói cho chúng ta biết kiểu dữ liệu này sử dụng bao nhiêu bit để lưu trữ. uint có nghĩa là "usigned integer" và int là "signed integer". Unsigned integer chỉ chứa các con số dương và số 0. Có 2 kiểu dữ liệu được đặt trùng tên là: byte tương tự như uint8rune tương tự như int32. Bytes là một đơn vị đo lường sử dụng phổ biến trong máy tính

 1 byte = 8 bits
 1024 bytes = 1 kilobyte
 1024 kilobytes = 1 megabyte
 …

và vì thế kiểu dữ liệu byte của Go thường được sử dụng để định nghĩa các kiểu dữ liệu khác. Và có 3 kiểu dữ liệu integer phụ thuộc vào kiến trúc máy tính là: uint,intanduintptr. Chúng phụ thuộc vào máy tính vì chúng có kích thước phụ thuộc vào kiến trúc máy tính mà bạn đang sử dụng.

Nhìn chung bạn làm việc với số nguyên thì thường nên sử dụng kiểu int.

Dấu chấm động (số thực)

Số dấu chấm động là số chứa phần thập phân (số thực). Như: 1.234, 123.4, 0.00001234, 12340000. Các xử lí chúng trên máy tính khá phức tạp, tạm thời chúng ta chưa cần quan tâm đến các chúng biểu diễn trong máy tính, chỉ cần biết cách sử dụng là được. Chỉ cần lưu ý các điều sau:

Go có 2 loại số chấm động là float32 và float64. và 2 loại bổ sung để biểu diễn các con số phức tạp complex64compex128.

Nhìn chung bạn làm việc với số dấu chấm động (số thực) thì thường nên sử dụng kiểu float64.

Ví dụ

Giờ hãy thử viết một chương trình sử dụng các con số. Đầu tiên chúng ta tạo thư mục tên là chapter3 và tạo 1 file main.go trong thư mục này có nội dung như sau:

package main

import "fmt"

func main() {
  fmt.Println("1 + 1", 1 + 1)
}

Nếu bạn chạy chương trình này bạn sẽ thấy như sau:

$ go run main.go
1 + 1 = 2

Chương trình trên này rất giống với chương trình ở chương 2. Nó chưa một dòng khai báo package, lệnh import tương tự, lệnh khai báo function tương tự và sử dụng giống luôn function Println. Nhưng lần này, thay vì xuất ra màn hình dòng chữ Hello World thì chúng ta in ra chuỗi 1 + 1 theo sau là một biểu thức 1+1. Biểu thức này gồm 3 phần là một con số 1 (kiểu int) phép tính + và một con số khác 1. Giờ ta thử làm tương tự với số chấm động:

fmt.Println("1 + 1 =", 1.0 + 1.0)

Lưu ý rằng chúng ta sử dụng thêm .0 ở phía sau con số 1 để báo cho Go biết rằng chúng ta đang sử dụng dấu chấm động thay vì số nguyên.

Chạy chương trình này, bạn cũng nhận được kết quả tương tự. Trong Go, có một số phép toán như sau:

+ cộng
- trừ
* nhân
/ chia
% chia lấy phần nguyên

Strings

Chúng ta thấy ở chapter 2 một chuỗi là một chuỗi các kí tự với độ dài xác định sử dụng để trình bày văn bản. String trong Go được tạo thành từ các byte, thường thì mỗi kí tự là 1 byte. Các kí tự khác như chữ TQ được lưu trữ nhiều hơn 1 byte.

String được tạo bằng các sử dụng dấu ngoặc kép "Hello World" hoặc dấu huyền `Hello World . Sự khác biệt là chuỗi được tạo từ dấu ngoặc kép không thể chứa các kí tự xuống dòng và các kí tự đặc biệt, như kí tự\nlà kí tự xuống dòng, hoặc\t` là kí tự tab.

Hãy sửa chương trình trước đó để xem thử:

package main

import "fmt"

func main() {
  fmt.Println(len("Hello World"))
  fmt.Println("Hello World"[1])
  fmt.Println("Hello " + "World")
}

Vài điều cần lưu ý:

Booleans


Source: http://www.golang-book.com/books/intro/3

---

Phuc Tran Hoang


Các bài viết khác

Bắt đầu
Phuc Tran Hoang

Kiểu dữ liệu - Types
Phuc Tran Hoang