Packages
Giới thiệu
- Packages(Gói) trong Go là một cách để tổ chức và tái sử dụng trong source code.
- Packages cho phép phân chia source code thành các phần nhỏ hơn, giúp dễ dàng quản lý code trong dự án
- Trong Golang, mỗi file đều thuộc một package. Tên của package là tên thư mục chứa file đó.
Sử dụng
-
Để sử dụng các chức năng từ một package khác, bạn cần import package đó vào file của mình. Cú pháp:
import "tên_package"
\Ví dụ: Import
"fmt"
để sử dụng các chức năng in và định dạng trong package fmt.Theo quy ước, tên gói giống với phần tử cuối cùng của đường dẫn nhập. Ví dụ: gói "math/rand" bao gồm các tệp bắt đầu bằng gói câu lệnh rand.
package main import ( "fmt" "math/rand" ) func main() { fmt.Println("My lucky number is", rand.Intn(100)) }
-
Go cung cấp nhiều packages chuẩn giúp thực hiện các công việc phổ biến như định dạng in ra đọc ghi file, network,...
-
Ngoài việc sử dụng các packages chuẩn, bạn có thể tạo và sử dụng các packages do chính bạn định nghĩa bằng cách file của mình trong cùng một thư mục và đặt tên thư mục là tên của package.
-
Trong các dự án lớn, việc quản lý dependency giữa các packages là rất quan trọng. Go modules là một cách để quản lý dependency và phiên bản của các packages.
Exported names
- Trong Go, một tên được export nếu nó bắt đầu bằng một chữ cái viết hoa. Ví dụ, "Hello" là một tên được export, cũng như "Pi", được export từ package "math".
- "hello" và "pi" không bắt đầu bằng một chữ cái viết hoa, vì vậy chúng không được export.
- Khi import một package, bạn chỉ có thể tham chiếu đến các tên được export của nó. Bất kỳ tên không được export(unexported) nào đều không thể truy cập từ bên ngoài package. Ví dụ:
// Trong file math.go
package math // Pi là một biến được export
const Pi = 3.14159 // pizza là một biến không được export
var hello = "Xin chào" // CalculateArea là một hàm được export
func CalculateArea(radius float64) float64 { return Pi * radius * radius
} // calculateVolume là một hàm không được export
func calculateVolume(radius float64) float64 { return (4.0 / 3.0) * Pi * radius * radius * radius
}
Functions
- Một function(hàm) có thể nhận không hoặc nhiều hơn một đối số.
// Hàm nhận 1 đối số
func greet(name string) { fmt.Println("Hello,", name)
} // Hàm không nhận đối số
func main() { greet("Alice")
}
- Functions continued: Khi hai hoặc nhiều tham số liên tiếp trong hàm có cùng một kiểu dữ liệu, bạn có thể bỏ qua kiểu dữ liệu ở tất cả trừ tham số cuối cùng.
// x int, y int có thể viêt ngắn thành x, y int
func add(a, b int) int { return a + b
} func main() { sum := add(3, 5) fmt.Println("Sum:", sum)
}
- Multiple results: Một hàm có thể trả về đồng thời nhiều kết quả
// Hàm divide trả về 2 giá trị
// 1: Kiểu float64: Kết quả a/b hoặc 0
// 2: error: một error hoặc nil
func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("cannot divide by zero") } return a / b, nil
} func main() { result, err := divide(10, 2) if err != nil { fmt.Println("Error:", err) return } fmt.Println("Result:", result)
}
- Named return values: Giá trị trả về của hàm trong Go có thể được đặt tên, các tên này nên được sử để mô tả ý nghĩa của giá trị trả về. Một return mà không có đối số trả về sẽ trả về các giá trị được đặt tên, điều này được gọi là "naked" return. Thường nó sẽ được sử dụng trong các hàm ngắn.
func split(sum int) (x, y int) { x = sum * 2 / 10 y = sum - x return
} func main() { fmt.Println(split(30)) // kết quả: 6 24
}
Variables
Khai báo và khởi tạo
- Khai báo variables(biến): Câu lệnh "var", có thể khai báo một hoặc nhiều biến
- Kiểu dữ liệu của biến được đặt ở cuối cùng sau tên biến Ví dụ:
var age int
var name string
var isActive bool
- Khởi tạo: Khởi tạo biến bằng cách gán giá trị cho biến sau dấu "=" Ví dụ:
var age int = 30
var name string = "Jim John"
var isActive bool = true
- Khai báo biến ngắn gọn: câu lệnh gán ngắn := có thể được sử dụng thay cho khai báo var với kiểu ẩn. Ví dụ:
age := 30
name := "Jim John"
isActive := true
Lưu ý: Cách khai báo biến này chỉ có thể dùng ở trong 1 hàm.
Các loại biến cơ bản
I - Số
Các số được chia thành ba loại con như sau:
1. Số nguyên (Integer)
Cả số nguyên có dấu và không dấu đều có sẵn trong bốn kích thước khác nhau như được hiển thị trong bảng dưới đây. Số nguyên có dấu được biểu diễn bằng int và số nguyên không dấu được biểu diễn bằng uint.
Các phép toán số học có thể thực hiện: Cộng, trừ, nhân, chia, phần dư
Data type | Description |
---|---|
int8 | 8-bit signed integer |
int16 | 16-bit signed integer |
int32 | 32-bit signed integer |
int64 | 64-bit signed integer |
uint8 | 8-bit unsigned integer |
uint16 | 16-bit unsigned integer |
uint32 | 32-bit unsigned integer |
uint64 | 64-bit unsigned integer |
int | Both int and uint contain same size, either 32 or 64 bit. |
uint | Both int and uint contain same size, either 32 or 64 bit. |
rune | It is a synonym of int32 and also represent Unicode code points. |
byte | It is a synonym of uint8. |
uintptr | t is an unsigned integer type. Its width is not defined, but its can hold all the bits of a pointer value. |
Ví dụ:
// Using 8-bit unsigned int var a uint8 = 225 fmt.Println(a, a-3) // Using 16-bit signed int var b int16 = 32767 fmt.Println(b+2, b-2) fmt.Println("Example of arithmetic operations:") var x int16 = 170 var y int16 = 83 //Addition fmt.Printf(" addition : %d + %d = %d\n ", x, y, x+y) //Subtraction fmt.Printf("subtraction : %d - %d = %d\n", x, y, x-y) //Multiplication fmt.Printf(" multiplication : %d * %d = %d\n", x, y, x*y) //Division fmt.Printf(" division : %d / %d = %d\n", x, y, x/y) //Modulus fmt.Printf(" remainder : %d %% %d = %d\n", x, y, x%y)
Output:
225 222
-32767 32765
Example of arithmetic operations: addition : 170 + 83 = 253 subtraction : 170 - 83 = 87 multiplication : 170 * 83 = 14110 division : 170 / 83 = 2 remainder : 170 % 83 = 4
2. Số thực (Float)
Số thực được chia thành 2 loại như bảng dưới.
Các phép toán số học có thể thực hiện: Cộng, trừ, nhân, chia.
Data type | Description |
---|---|
float32 | 32-bit IEEE 754 floating-point number |
float64 | 64-bit IEEE 754 floating-point number |
Ví dụ:
a := 20.45 b := 34.89 c := b-a // Display the result fmt.Printf("Result is: %f", c) // Display the type of c variable fmt.Printf("\nThe type of c is : %T", c)
Output:
Result is: 14.440000
The type of c is : float64
3. Số phức (Complex)
Số phức (Complex Numbers): Các số phức được chia thành hai phần như được hiển thị trong bảng dưới đây. float32 và float64 cũng là một phần của các số phức này. Hàm tích hợp sẵn tạo ra một số phức từ phần ảo và phần thực của nó và hàm ảo và thực tích hợp sẵn trích xuất các phần đó.
Data type | Description |
---|---|
complex64 | Complex numbers which contain float32 as a real and imaginary component. |
complex128 | Complex numbers which contain float64 as a real and imaginary component. |
Ví dụ:
var a complex128 = complex(6, 2) var b complex64 = complex(9, 2) fmt.Println(a) fmt.Println(b) // Display the type fmt.Printf("The type of a is %T and "+ "the type of b is %T", a, b)
Output:
(6+2i)
(9+2i)
The type of a is complex128 and the type of b is complex64
II - Booleans
Kiểu dữ liệu boolean đại diện cho chỉ một bit thông tin có thể là true hoặc false. Các giá trị của kiểu boolean không được chuyển đổi một cách ngầm định hoặc rõ ràng sang bất kỳ kiểu dữ liệu nào khác.
Ví dụ:
// variables str1 := "GolangEssentials" str2:= "golangEssentials" str3:= "golangessentials" result1:= str1 == str2 result2:= str1 == str3 // Display the result fmt.Println( result1) fmt.Println( result2) // Display the type of // result1 and result2 fmt.Printf("The type of result1 is %T and "+ "the type of result2 is %T", result1, result2)
Output:
false
false
The type of result1 is bool and the type of result2 is bool
II - Strings
Kiểu dữ liệu chuỗi (string) đại diện cho một chuỗi các điểm mã Unicode. Hay nói cách khác, ta có thể nói rằng một chuỗi là một chuỗi các byte không thể thay đổi, có nghĩa là một khi một chuỗi đã được tạo ra thì bạn không thể thay đổi chuỗi đó. Một chuỗi có thể chứa dữ liệu tùy ý, bao gồm cả byte có giá trị không trong dạng có thể đọc được cho con người. Các chuỗi có thể được ghép lại bằng toán tử cộng (+).
Ví dụ:
// str variable which stores strings str := "GolangEssentials" // Display the length of the string fmt.Printf("Length of the string is:%d",len(str)) // Display the string fmt.Printf("\nString is: %s", str) // Display the type of str variable fmt.Printf("\nType of str is: %T", str)
Output:
Length of the string is:16
String is: GolangEssentials
Type of str is: string
Một số lưu ý
- Default value: Các biến được khai báo mà không có giá trị khởi tạo rõ ràng sẽ được gán giá trị default: 0 đối với kiểu số, false đối với kiểu bolean và ""(the empty string) với chuỗi
var i int var f float64 var b bool var s string fmt.Printf("%v %v %v %q\n", i, f, b, s)
Output:
0 0 false ""
- Ép kiểu: Trong Go, các kiểu dữ liệu có thể chuyển đổi bằng cách sử dụng toán tử type(value) \
a := 5 //int b := 3.4 //float64 sumFloat := float64(a) + b fmt.Println(sumFloat) // Output = 8.4 sumInt := a + int(b) fmt.Println(sumInt) // Output = 8
- Hằng số(constants): Hằng số được khai báo giống như biến, nhưng sử dụng từ khóa const. Hằng số có thể là ký tự, chuỗi, boolean, hoặc giá trị số. Không thể khai báo hằng số bằng cú pháp :=. package main
import "fmt"
const Pi = 3.14
func main() { const World = "Jim John" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day")
const Truth = true
fmt.Println("Go rules?", Truth)
}
Kết bài
Trong bài thứ 2 này mình đã giới thiệu với các bạn những khái niệm cơ bản cũng như quan trọng nhất về package, hàm và biến. Còn rất nhiều loại biến thú vị nữa mà mình sẽ tiếp tục giới thiệu ở những bài viết sau 😄 Nếu có thắc mắc hoặc phát hiện bài viết có thiếu sót gì, hãy comment cho mình biết để mình kịp thời chỉnh sửa cũng như cùng thảo luận về thắc mắc đó nhé 😉 Hi vọng những kiến thức này sẽ giúp ích được các bạn trong hành trình chinh phục Golang. Hẹn gặp lại ở những bài viết tiếp theo trong series Golang Essentials: Nền Tảng và Kiến Thức Cơ Bản. See ya!