1. Biến và Hằng số
Trong Golang, biến và hằng số là hai khái niệm cơ bản có vai trò rất quan trọng trong một chương trình.
- Một biến là một bí danh được sử dụng để lưu trữ dữ liệu trong một chương trình. Trong Golang, từ khóa
var
được sử dụng để khai báo biến. - Một hằng số là một bí danh mà giá trị không thể thay đổi trong chương trình. Trong Golang, từ khóa
const
được sử dụng để khai báo hằng số.
2 Khai báo và Khởi tạo biến trong Golang
2.1 Khai báo và Gán giá trị cho Một Biến Đơn
Trong ngôn ngữ Go, từ khóa var
được sử dụng để khai báo biến theo định dạng var tên_biến kiểu_dữ_liệu
. Sau khi khai báo, biến có thể được gán giá trị trong code tiếp theo, hoặc có thể được khởi tạo trực tiếp tại thời điểm khai báo. Ví dụ:
var age int // Khai báo một biến kiểu số nguyên là age
age = 25 // Gán giá trị cho biến
var name string = "Alice" // Khai báo và khởi tạo biến name
2.2 Khai báo nhiều Biến cùng lúc
Ngôn ngữ Golang hỗ trợ khai báo đồng thời nhiều biến, điều này giúp làm cho code trở nên ngắn gọn hơn. Thông thường, việc khai báo nhiều biến được thực hiện ở đầu của một hàm hoặc tại cấp độ package. Ví dụ:
var (
firstName, lastName string
age int
)
firstName = "John"
lastName = "Doe"
age = 30
Trong khai báo đồng loạt ở trên, firstName
và lastName
được khai báo là chuỗi, trong khi age
là một số nguyên.
2.3 Suy luận Kiểu và Khai báo biến ngắn gọn
Trong ngôn ngữ Go, không luôn cần phải chỉ định rõ kiểu của biến. Nếu có biểu thức khởi tạo được cung cấp khi khai báo biến, Go có thể suy luận được kiểu của biến. Điều này được gọi là suy luận kiểu. Khai báo biến ngắn gọn sử dụng :=
có thể làm cho câu lệnh khai báo và khởi tạo biến dựa trên suy luận kiểu trở nên đơn giản. Ví dụ:
city := "Beijing" // Sử dụng khai báo biến ngắn gọn để đồng thời khai báo và khởi tạo city
country := "China" // country được suy luận là kiểu chuỗi
Cần lưu ý rằng khai báo biến ngắn gọn chỉ có thể được sử dụng trong các hàm và không thể được sử dụng ở phạm vi toàn cục.
2.4 Khai báo biến ở bên ngoài các Hàm
Các biến được khai báo ở bên ngoài các hàm có phạm vi ở cấp độ package. Các biến này có thể nhìn thấy và truy cập trong toàn bộ package. Ví dụ:
var globalVar string = "I am global" // Khai báo một biến toàn cục
func printGlobalVar() {
fmt.Println(globalVar) // Truy cập biến toàn cục trong hàm
}
Các biến toàn cục có thể được chia sẻ giữa bất kỳ hàm nào trong package, nhưng cần được sử dụng cẩn thận để tránh xung đột tên và tham chiếu không rõ ràng.
Mẹo: Ở đây chỉ cần hiểu mã chức năng cơ bản, giải thích chi tiết về chức năng sẽ được cung cấp trong các phần sau.
3. Các Kiểu Dữ Liệu Cơ Bản và Giá trị Zero
3.1 Các Kiểu Dữ Liệu Cơ Bản trong Golang
Trong ngôn ngữ Go, mỗi loại biến cung cấp ngữ nghĩa và đặc tính hành vi rõ ràng. Dưới đây là một số loại dữ liệu cơ bản phổ biến:
-
int
,int8
,int16
,int32
,int64
: Các loại số nguyên có phạm vi khác nhau -
uint
,uint8
,uint16
,uint32
,uint64
: Số nguyên không dấu -
float32
,float64
: Số dấu chấm động -
bool
: Giá trị logic (true hoặc false) -
string
: Chuỗi
3.2 Khái niệm Giá trị Zero
Trong ngôn ngữ Go, biến được tự động khởi tạo với giá trị zero của kiểu dữ liệu tương ứng sau khi được khai báo. Giá trị zero là giá trị mặc định của kiểu tương ứng khi một biến không được khởi tạo một cách rõ ràng. Điều này không phổ biến trong một số ngôn ngữ khác, nhưng trong Go, điều này đảm bảo rằng tất cả các biến luôn có một giá trị khởi tạo hợp lệ. Dưới đây là giá trị zero của mỗi kiểu dữ liệu cơ bản:
- Giá trị zero cho một số nguyên là
0
- Giá trị zero cho một số dấu chấm động là
0.0
- Giá trị zero cho một giá trị logic là
false
- Giá trị zero cho một chuỗi là một chuỗi rỗng
""
Ví dụ:
var i int // Giá trị zero là 0
var f float64 // Giá trị zero là 0.0
var b bool // Giá trị zero là false
var s string // Giá trị zero là ""
Hiểu rõ khái niệm giá trị zero rất quan trọng, vì nó có thể giúp nhà phát triển hiểu rõ hành vi của việc khởi tạo biến và có thể được sử dụng để ngăn ngừa lỗi con trỏ rỗng hoặc chưa khởi tạo.
4. Phạm vi của Biến
4.1 Biến Cục Bộ
Biến cục bộ là các biến được định nghĩa trong một hàm và chỉ có thể truy cập trong phạm vi của hàm đó. Các tham số hàm cũng thuộc về biến cục bộ. Từ lúc được tạo ra cho đến khi thực thi hàm hoàn thành, các biến cục bộ sẽ biến mất. Mỗi khi một hàm được gọi, các biến cục bộ lại được tạo mới.
func localVariableExample() {
var localVariable int = 10 // Đây là một biến cục bộ
fmt.Println(localVariable)
}
func main() {
localVariableExample() // Output: 10
// fmt.Println(localVariable) // Điều này sẽ gây lỗi biên dịch vì localVariable không có thể nhìn thấy ở đây
}
Trong ví dụ trên, localVariable
chỉ có thể truy cập trong hàm localVariableExample
.
4.2 Biến Toàn Cục
Biến toàn cục là các biến được định nghĩa bên ngoài các hàm, và chúng có thể được truy cập trong bất kỳ tệp nào trong cùng gói. Nếu bạn muốn sử dụng biến toàn cục trong các gói khác, tên biến phải bắt đầu bằng chữ cái in hoa, phù hợp với quy tắc kiểm soát truy cập của Go.
package main
import "fmt"
var globalVariable int = 20 // Đây là một biến toàn cục
func main() {
fmt.Println(globalVariable) // Output: 20
changeGlobal()
fmt.Println(globalVariable) // Output: 30
}
func changeGlobal() {
globalVariable = 30 // Thay đổi giá trị của biến toàn cục
}
Trong ví dụ này, globalVariable
có thể thấy ở cả hàm main
và hàm changeGlobal
.
5 Khai Báo và Sử Dụng Hằng
5.1 Từ Khóa const
Chúng ta sử dụng từ khóa const
để định nghĩa các hằng. Hằng số là các giá trị không thể được thay đổi và một khi được định nghĩa, giá trị của chúng không thể thay đổi. Hằng có thể là bất kỳ kiểu dữ liệu cơ bản nào như số nguyên, số thực, boolean hoặc chuỗi.
const Pi = 3.14 // Khai báo một hằng số số thực
const StrConst string = "Xin chào, thế giới!" // Khai báo một hằng số chuỗi
func main() {
fmt.Println(Pi)
fmt.Println(StrConst)
}
5.2 Hằng Enum
Ngôn ngữ Go không có một kiểu liệt kê cụ thể, nhưng bạn có thể sử dụng từ khóa iota
để đạt được việc liệt kê. Trong một khối const
, mỗi khai báo hằng số bổ sung sẽ tăng giá trị của iota
lên 1.
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
func main() {
fmt.Println(Sunday) // Output: 0
fmt.Println(Saturday) // Output: 6
}
Đoạn code trên khai báo một liệt kê cho các ngày trong tuần, trong đó iota
khởi tạo ở 0 trong khối const
và tăng lên 1 cho mỗi khai báo sau đó.
5.3 Phạm Vi của Hằng
Phạm vi của hằng tương tự như biến. Nếu một hằng được định nghĩa trong một hàm, phạm vi của nó chỉ giới hạn trong hàm đó. Nếu một hằng được định nghĩa bên ngoài một hàm (toàn cục), phạm vi của nó là toàn bộ gói, và nếu chữ cái đầu tiên là in hoa, nó có thể được truy cập trong các gói khác.
Quản lý phạm vi của hằng giúp giảm ô nhiễm phạm vi toàn cục và cải thiện tính bảo trì và đọc hiểu của chương trình.
const GlobalConst = "Đây là hằng số toàn cầu"
func main() {
const LocalConst = "Đây là hằng số cục bộ"
fmt.Println(GlobalConst) // Điều này hợp lệ
fmt.Println(LocalConst) // Điều này hợp lệ
}
func anotherFunction() {
// fmt.Println(LocalConst) // Điều này sẽ gây lỗi biên dịch: LocalConst không thể nhìn thấy trong hàm này
fmt.Println(GlobalConst) // Điều này hợp lệ
}