Go basic
Tags: go, tutorial, vietnameseblogs
Published: 2022-08-17 09:28:00

- Tải Go và set up environment config Linux:

> sudo apt update
sudo apt upgrade
sudo apt install golang-go
source ~/.bash_profile
go version
Sau khi cài đặt và set up xong, sử dụng câu lệnh:
> go env
Workplace environment variable sẽ hiện ở GOPATH: /home/tuan/.go(tùy từng máy)

- Workspace:dùng để import các custom package vào project.
Đầu tiên phải truy cập các folder chứa package đã viết dùng câu lệnh:
go mod init [tên modules]/package(tên modules thường là tên project)

Sau khi tạo xong truy cập folder project và dùng câu lệnh:
go work init để tạo ra một file go.work. Viết các đường dẫn đến package đã viết. 

Vậy là các custom package đã có thể sử dụng.
- Go CLI:
build: biên dịch thành ứng dụng.
clean: xóa files
install: cài đặt package
get -u: tải và cài đặt package
list: liệt kê các package
run: biên dịch chạy chương trình
fix: tool fix package
test: test package
version: version go đã cài
env: hiển thị thông tin go environment

- Các kiến thức cơ bản:

1. Variables:
`var` dùng để tạo 1 hay nhiều giá trị.
Go sẽ tự đề xuất kiểu dữ liệu đã được tạo.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q35j1kazqel61xs6qg7r.png)
Có 2 cách khai báo: 
1) var a = "hello"
2) a := "hello"

2. Constant
`const` dùng để tạo hằng số (biến có giá trị không đổi). const không thể được gán với 1 giá trị được trả về bởi hàm. Ngoài ra hằng số chuỗi có 1 số trường hợp sau:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lhv3x2p59m72wgibhgf0.png)
Nhưng khi cho a = b thì chương trình bị lỗi do a và b khác kiểu dữ liệu.

3.Type:
 - Basic type: int, float, complex, string, booleans.
 - Aggregate type: Array, struct.
 - Reference type: Pointer, slice, maps, function, channel, buffer channel,...
 - Interface type

4.Function

Thủ tục hàm dùng để thực hiện một nhiệm vụ nhất định. Hàm nhận input vào xử lý và trả về output.
Cách khai báo:
`func plus(a int, b int) int{
     return (a + b)
}`
input: a,b có kiểu dữ liệu là int
output: có kiểu dữ liệu là int và kết quả a + b

5.Packages

Mọi chương trình go đều có packages.
Package giống như thư viện hàm hỗ trợ sẵn của go.

-----

- Array: là mảng chứa các phần tử và số lượng phần tử cố định (không thể thay đổi).Phải biết số lượng phần tử lúc tạo.

`a := []int{7, 2, 8, -9, 4, 0}`

`var a[5]string`
- Slice: là mảng chứa các phần tử và thay đổi được số lương phần tử. Không cần biết số phần tử lúc tạo.

<u>Ví dụ:</u>
s := make([]string,3)
var b []string
a[2:] xóa 2 phần tử đầu tiên.
a = append(a, 3): thêm 3 vào cuối slice
- Map: là kiểu dữ liệu key: value.

`type months map[string] int
m := months{"Jan":31, "Feb":28}`

-----

> **OOP --------> Go
Encapsulation --> Packages
Inheritance ----> Composition
Polymorphism ---> Interfaces
Abstraction ----> Embedding**

- Pointer: là lấy giá trị của biến địa chỉ đã cho(tham chiếu ngược). Gía trị 0 có con trỏ là nil. Go không hỗ trợ phép toán trên con trỏ.
`b := []int{1,2}
 a := &b (khi đó *a = b)
 a++`

- Struct: Giống như struct ngôn ngữ C.
Cách định nghĩa:
`type Person struct{
    name string
    age int
}`
`type Skills [] string
type Student struct{
    Person
    Skills
    specialty string
}`

> **Khi khởi tạo struct, hãy sử dụng tên của thuộc tính**
Giả sử thêm thuộc tính vào struct thì chương trình vẫn chạy bình thường.

- Methods: function có input vào là struct hoặc non-struct.

> Những lưu ý khi dùng methods:
 - Nếu 2 methods cùng tên thì phải thuộc 2 struct khác nhau(đối với hàm thì không được trùng tên còn method thì được nếu kiểu dữ liệu khác nhau).
 - Method có nhận kiểu dữ liệu là con trỏ

- Interface: là tổng hợp các method của struct.(struct có tất cả phương thức trong một interface thì struct đó được gọi là implement interface đó)

-----

- GoRoutine: Dùng để xử lý đồng thời nhiều tác vụ. Được quản lý bởi package runtime và không phụ thuộc bởi phần cứng. 1 goroutine bắt đầu vùng nhớ stack nhỏ. Khi chương trình chạy k đủ không gian stack, goroutine sẽ tự động tăng không gian stack. Khi 1 chương trình chạy xong thì goroutine sẽ tự hủy. Vì không biết hàm goroutine bao lâu thực hiện nên sẽ dùng đến channel hoặc sync.WaitGroup. Cú pháp goroutine là:

`go func(){*to do*}()`
- Channel: Dùng để kết nối các goroutines để chia sẻ dữ liệu. Cú pháp khởi tạo:

`c:= make(chan int)` là channel chứa dữ liệu int
Gửi dữ liệu vào channel: `c <-`
Nhập dữ liệu từ channel: `<- c`
Khi chỉ khai báo channel mà k có goroutine sẽ lỗi vì chưa có đầu nhận dữ liệu.
- Channel Buffer: kết hợp goroutine và channel. Có giới hạn số lượng gửi dữ liệu vào.
Khởi tạo: `c: = make(chan int,2)` 
- Select: Dùng để điều khiển gửi và nhập dữ liệu của channel(giống switch nhưng khác điều kiện là gửi và nhập dữ liệu của channel)
- Mutex: Dùng để ngăn chặn truy cập một vùng nhớ bởi nhiều Routine trong cùng một thời điểm. Mutex có 2 phương thức Lock() và Unlock() quản lý bởi package sync. Cách khai báo:
`var mu sync.Mutex`

> **Lưu ý:** Khi thao tác ảnh hưởng đến 1 dữ liệu ví dụ là 3 trong goroutines thì ứng với từng goroutine giá trị 3 sẽ thay đổi khác nhau nên khi trả về kết quả sẽ sai. Thay vào đó ta thêm mutex sẽ đảm bảo giá trị 3 qua từng go routine đều lấy đúng kết quả sau từng lần chạy.

-----
- Defer:
- Error:
- Panic:
- Recover: