Golang là một ngôn ngữ mới mẻ, hiệu quả mà đơn giản, sau khi học có thể đạt được mức thu nhập rất cao so với thị trường công nghệ thông tin. Golang đặc biệt mạnh mẽ trong lĩnh vực phát triển web và vận hành các ứng dụng phía máy chủ một cách hiệu quả, những yếu tố đang được săn tìm bởi các dự án “triệu đô”. Ngoài ra, Go cũng đang được ưa chuộng trong lĩnh vực blockchain, một lĩnh vực đang từng ngày thay đổi cả ngành tài chính thế giới. Bài viết này sẽ hướng dẫn cho những bạn hoàn toàn mới với ngành công nghệ thông tin và chưa có nhiều kiến thức về lập trình muốn học Golang cơ bản.
Đọc bài viết để hiểu rõ:
- Golang cơ bản là gì?
- Các thuật ngữ Golang cơ bản
- Cú pháp cơ bản của Golang
- Câu hỏi thường gặp về Golang
Golang cơ bản là gì?
Trước khi hiểu được Golang cơ bản là gì, hãy cùng xem qua khái niệm về ngôn ngữ lập trình:
Ngôn ngữ lập trình là một tập hợp các chỉ thị nhằm tạo ra các chương trình cho phép máy tính thực hiện các tác vụ cụ thể. Ngôn ngữ lập trình gồm hai loại, mỗi ngôn ngữ có những đặc điểm nổi bật phù hợp với các loại tác vụ và ngành công nghiệp khác nhau:
- Ngôn ngữ cấp cao, gần với ngôn ngữ con người, ví dụ: Python, JavaScript.
- Ngôn ngữ cấp thấp, gần với ngôn ngữ máy, ví dụ: Golang, C++.
Golang (hay Go) là một ngôn ngữ lập trình được phát triển bởi các kỹ sư của Google, nhằm đáp ứng nhu cầu của việc phát triển phần mềm hiện đại. Golang nhấn mạnh sự đơn giản và hiệu quả, trở thành sự lựa chọn tuyệt vời cho mọi thứ từ lập trình microservices đến các hệ thống phân tán quy mô lớn.
Để tìm hiểu thêm về Golang, bạn hãy dùng công cụ chạy Golang được cài đặt sẵn của w3schools. Sau khi đã nắm rõ Golang cơ bản là gì, bạn có thể xem tiếp các nội dung dưới đây để tìm hiểu chi tiết về Golang.
Các khái niệm Golang cơ bản
Hello World
“Hello world” là cách chạy 1 đoạn chương trình để in ra từ “Hello World” trên màn hình. Khi bắt đầu với bất cứ ngôn ngữ mới nào, người học đều thực hành với thao tác này. Hãy xem xét đoạn mã sau:
package main import ("fmt") func main() { fmt.Println("Hello World!") }
Theo ví dụ trên, một tệp Go bao gồm các phần cơ bản sau:
- Khai báo package
- Import package vào tệp
- Các hàm (func)
- Các câu lệnh và biểu thức
Chú thích
Chú thích một dòng trong Go:
- Chú thích một dòng bắt đầu với hai dấu gạch chéo (//).
- Bất kỳ văn bản nào nằm giữa // và cuối dòng sẽ bị trình biên dịch bỏ qua (không được thực thi).
// Đây là một comment package main import ("fmt") func main() { // day la 1 comment fmt.Println("Hello World!") // Đây là một comment }
Chú thích nhiều dòng trong Go:
- Chú thích nhiều dòng bắt đầu với /* và kết thúc với */.
- Bất kỳ văn bản nào nằm giữa /* và */ sẽ bị trình biên dịch bỏ qua.
package main import ("fmt") func main() { /* The code below will print Hello World to the screen, and it is amazing */ fmt.Println("Hello World!") }
Biến
Trong Go, có nhiều loại biến khác nhau, ví dụ:
- int – lưu trữ số nguyên (số toàn phần), như 123 hoặc -123
- float32 – lưu trữ số thực với phần thập phân, như 19.99 hoặc -19.99
- string – lưu trữ văn bản, như “Hello World”. Giá trị chuỗi được bao quanh bởi dấu ngoặc kép
- bool – lưu trữ giá trị với hai trạng thái: true hoặc false
Trong Go, có hai cách để khai báo biến:
- Từ khóa var
- Với dấu :=
package main import ("fmt") func main() { var student1 string = "John" //type is string var student2 = "Jane" //type is inferred x := 2 //type is inferred fmt.Println(student1) fmt.Println(student2) fmt.Println(x) }
Hằng số
Nếu một biến cần có giá trị cố định không thay đổi được, bạn có thể sử dụng từ khóa const để khai báo.
package main import ("fmt") const PI = 3.14 func main() { fmt.Println(PI) }
Mảng (Array)
Mảng được sử dụng để lưu trữ nhiều giá trị cùng một kiểu trong một biến duy nhất, thay vì khai báo riêng lẻ các biến cho mỗi giá trị.
Trong Golang, có hai cách để khai báo Mảng giống với khai báo biến:
- Từ khóa var
- Với dấu :=
package main import ("fmt") func main() { var arr1 = [3]int{1,2,3} arr2 := [5]int{4,5,6,7,8} fmt.Println(arr1) fmt.Println(arr2) }
Dưới đây là các thao tác cơ bản với Mảng:
- Truy cập phần tử
Bạn có thể truy cập một phần tử mảng cụ thể bằng cách tham chiếu đến số chỉ mục. Trong Go, chỉ mục mảng bắt đầu từ 0. Điều này có nghĩa là [0] là phần tử đầu tiên, [1] là phần tử thứ hai, v.v.
package main import ("fmt") func main() { prices := [3]int{10,20,30} fmt.Println(prices[0]) fmt.Println(prices[2]) }
- Thay đổi phần tử của Mảng
Bạn cũng có thể thay đổi giá trị của một phần tử mảng cụ thể bằng cách tham chiếu đến số chỉ mục.
package main import ("fmt") func main() { prices := [3]int{10,20,30} prices[2] = 50 fmt.Println(prices) }
- Khởi tạo Mảng
Nếu một mảng hoặc một trong các phần tử của nó không được khởi tạo trong code, nó sẽ được gán giá trị mặc định của kiểu dữ liệu đó. Mẹo nhỏ: Giá trị mặc định cho kiểu int là 0, và giá trị mặc định cho kiểu string là “”.
package main import ("fmt") func main() { arr1 := [5]int{} //not initialized arr2 := [5]int{1,2} //partially initialized arr3 := [5]int{1,2,3,4,5} //fully initialized fmt.Println(arr1) fmt.Println(arr2) fmt.Println(arr3) }
Mảng động (Slice)
Mảng động trong Go rất giống với mảng nhưng chúng linh hoạt và mạnh mẽ hơn. Giống như mảng, mảng động cũng được sử dụng để lưu trữ nhiều giá trị cùng một kiểu trong một biến đơn lẻ. Tuy nhiên, khác với mảng, chiều dài của mảng động có thể tăng hoặc giảm tùy ý.
Trong Go, có một số cách để tạo một mảng động:
Cách 1: Sử dụng định dạng []kieu_du_lieu{gia_tri}
Bạn có thể trực tiếp khởi tạo mảng động với các giá trị cụ thể, mà không cần xác định chiều dài, vì chiều dài sẽ được suy luận từ các giá trị được cung cấp.
Ví dụ:
package main import ("fmt") func main() { myslice1 := []int{} fmt.Println(len(myslice1)) fmt.Println(cap(myslice1)) fmt.Println(myslice1) myslice2 := []string{"Go", "Slices", "Are", "Powerful"} fmt.Println(len(myslice2)) fmt.Println(cap(myslice2)) fmt.Println(myslice2) }
Cách 2: Tạo mảng động từ một mảng
Bạn có thể tạo một mảng động từ một mảng bằng cách sử dụng cú pháp cắt. Cú pháp này cho phép bạn chỉ định khoảng của mảng mà bạn muốn tạo thành mảng động.
Ví dụ:
package main import ("fmt") func main() { arr1 := [6]int{10, 11, 12, 13, 14,15} myslice := arr1[2:4] fmt.Printf("myslice = %v\n", myslice) fmt.Printf("length = %d\n", len(myslice)) fmt.Printf("capacity = %d\n", cap(myslice)) }
Cách 3: Sử dụng hàm make()
Hàm make() được sử dụng để khởi tạo mảng động, nơi bạn có thể chỉ định kiểu dữ liệu, chiều dài ban đầu, và dung lượng tối đa (không bắt buộc).
Ví dụ:
package main import ("fmt") func main() { myslice1 := make([]int, 5, 10) fmt.Printf("myslice1 = %v\n", myslice1) fmt.Printf("length = %d\n", len(myslice1)) fmt.Printf("capacity = %d\n", cap(myslice1)) // with omitted capacity myslice2 := make([]int, 5) fmt.Printf("myslice2 = %v\n", myslice2) fmt.Printf("length = %d\n", len(myslice2)) fmt.Printf("capacity = %d\n", cap(myslice2)) }
Ngoài ra còn có các thao tác sau để tương tác với mảng động (tương tự như với mảng) mà bạn có thể tìm hiểu thêm:
- Truy cập phần tử
- Thay đổi phần tử
- Thêm phần tử
- Thêm mảng động vào mảng động
- Thay đổi chiều dài của mảng động
Toán tử
Dưới đây là các loại toán tử trong Golang cơ bản:
- Toán tử số học
Các toán tử số học được sử dụng để thực hiện các phép toán toán học phổ biến.
Toán tử |
Tên | Mô tả | Ví dụ |
+ | Cộng | Cộng hai giá trị lại với nhau |
x + y |
– |
Trừ | Trừ một giá trị khỏi giá trị khác | x – y |
* | Nhân | Nhân hai giá trị với nhau |
x * y |
/ |
Chia | Chia một giá trị cho giá trị khác | x / y |
% | Chia lấy dư | Trả về phần dư của phép chia |
x % y |
++ |
Tăng một đơn vị | Tăng giá trị của một biến lên 1 | x++ |
— | Giảm một đơn vị | Giảm giá trị của một biến đi 1 |
x– |
- Toán tử gán
Các toán tử gán được sử dụng để so sánh hai giá trị, thường là trong các điều kiện logic để quyết định dòng chảy của chương trình.
Toán tử |
Ví dụ |
Tương đương |
= |
x = 5 | x = 5 |
+= | x += 3 |
x = x + 3 |
-= |
x -= 3 | x = x – 3 |
*= | x *= 3 |
x = x * 3 |
/= |
x /= 3 | x = x / 3 |
%= | x %= 3 |
x = x % 3 |
&= |
x &= 3 | x = x & 3 |
|= | x |= 3 |
x = x | 3 |
^= |
x ^= 3 | x = x ^ 3 |
>>= | x >>= 3 |
x = x >> 3 |
<<= |
x <<= 3 |
x = x << 3 |
- Toán tử so sánh
Các toán tử so sánh dùng để so sánh hai giá trị.
Toán tử |
Tên | Ví dụ |
== | Bằng với |
x == y |
!= |
Không bằng | x != y |
> | Lớn hơn |
x > y |
< |
Nhỏ hơn | x < y |
>= | Lớn hơn hoặc bằng |
x >= y |
<= |
Nhỏ hơn hoặc bằng | x <= y |
- Toán tử logic
Các toán tử logic được sử dụng để kết hợp các biểu thức Boolean. Chúng rất hữu ích trong việc xây dựng các điều kiện phức tạp trong lập trình.
Toán tử |
Tên | Mô tả | Ví dụ |
&& | Logical AND | Trả về true nếu cả hai biểu thức đều đúng |
x < 5 && x < 10 |
|| |
Logical OR | Trả về true nếu một trong hai biểu thức đúng | x < 5 || x < 4 |
! | Logical NOT | Đảo ngược kết quả, trả về false nếu kết quả là true |
!(x < 5 && x < 10) |
- Toán Tử Bitwise
Các toán tử bitwise thực hiện thao tác trên các bits và thường được sử dụng trong lập trình hệ thống để thực hiện tối ưu hóa hiệu năng.
Toán tử |
Tên | Mô tả |
Ví dụ |
& |
AND | Thiết lập từng bit thành 1 nếu cả hai bit tương ứng là 1 | x & y |
| | OR | Thiết lập từng bit thành 1 nếu một trong hai bit là 1 |
x | y |
^ |
XOR | Thiết lập từng bit thành 1 nếu chỉ một trong hai bit là 1 | x ^ y |
<< |
Zero fill left shift | Dịch trái và điền 0 vào phía bên phải | x << 2 |
>> | Signed right shift | Dịch phải và sao chép bit cực trái vào từ phía bên trái, và để các bit cực phải rơi ra | x >> 2 |
Câu lệnh if – else
- Sử dụng câu lệnh if để chỉ định một khối mã Go được thực thi nếu điều kiện là đúng.
- Sử dụng câu lệnh else để chỉ định một khối mã được thực thi nếu điều kiện là sai.
package main import ("fmt") func main() { time := 20 if (time < 18) { fmt.Println("Good day.") } else { fmt.Println("Good evening.") } }
Vòng lặp
Vòng lặp thực thi một khối mã một số lần được chỉ định trước. Chỉ có một loại vòng lặp duy nhất có sẵn trong Go. Tính năng này rất hữu ích nếu bạn muốn chạy cùng một đoạn mã đi đi lại lại, mỗi lần với một giá trị khác nhau. Mỗi lần thực thi của vòng lặp được gọi là một lần lặp.
Vòng lặp for có thể nhận tối đa ba câu lệnh:
- Câu lệnh 1: Khởi tạo giá trị đếm của vòng lặp.
- Câu lệnh 2: Được đánh giá cho mỗi lần lặp. Nếu đánh giá là TRUE, vòng lặp tiếp tục. Nếu đánh giá là FALSE, vòng lặp kết thúc.
- Câu lệnh 3: Tăng giá trị bộ đếm của vòng lặp.
package main import ("fmt") func main() { for i:=0; i < 5; i++ { fmt.Println(i) } }
Hàm
Một hàm là một khối các câu lệnh có thể được sử dụng đi sử dụng lại nhiều lần trong một chương trình. Hàm sẽ không tự động thực thi khi một trang tải. Hàm sẽ được thực thi thông qua một lời gọi đến hàm đó.
Để tạo (hay khai báo) một hàm, ta làm như sau:
- Sử dụng từ khóa func.
- Xác định một tên cho hàm, theo sau là cặp dấu ngoặc đơn ().
- Cuối cùng, thêm mã định nghĩa hàm sẽ làm gì, bên trong cặp ngoặc nhọn {}.
Ví dụ khai báo hàm:
package main import ("fmt") func myMessage() { fmt.Println("I just got executed!") } func main() { myMessage() // call the function }
Cấu trúc (Struct)
Một struct (viết tắt của structure – cấu trúc) được sử dụng để tạo một tập hợp các thành phần thuộc nhiều kiểu dữ liệu khác nhau trong một biến đơn. Cấu trúc có thể hữu ích cho việc nhóm dữ liệu lại với nhau để tạo thành các bản ghi.
Trong khi mảng được sử dụng để lưu trữ nhiều giá trị của cùng một kiểu dữ liệu trong một biến đơn, các cấu trúc được sử dụng để lưu trữ nhiều giá trị của nhiều kiểu dữ liệu khác nhau trong một biến đơn.
Để khai báo một cấu trúc trong Go, sử dụng các từ khóa type và struct:
package main import ("fmt") type Person struct { name string age int job string salary int } func main() { var pers1 Person var pers2 Person // Pers1 specification pers1.name = "Hege" pers1.age = 45 pers1.job = "Teacher" pers1.salary = 6000 // Pers2 specification pers2.name = "Cecilie" pers2.age = 24 pers2.job = "Marketing" pers2.salary = 4500 // Access and print Pers1 info fmt.Println("Name: ", pers1.name) fmt.Println("Age: ", pers1.age) fmt.Println("Job: ", pers1.job) fmt.Println("Salary: ", pers1.salary) // Access and print Pers2 info fmt.Println("Name: ", pers2.name) fmt.Println("Age: ", pers2.age) fmt.Println("Job: ", pers2.job) fmt.Println("Salary: ", pers2.salary) }
Bản Đồ (Map)
Một bản đồ là một tập hợp không có thứ tự và có thể thay đổi, không cho phép các phần tử trùng lặp. Mỗi phần tử trong một bản đồ là một cặp khóa:giá trị (key:value). Độ dài của một bản đồ là số lượng các phần tử của nó, bạn có thể kiểm tra bằng cách sử dụng hàm len(). Giá trị mặc định của một bản đồ là nil.
Dưới đây là ví dụ cách tạo bản đồ sử dụng var và :=
package main import ("fmt") func main() { var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964"} b := map[string]int{"Oslo": 1, "Bergen": 2, "Trondheim": 3, "Stavanger": 4} fmt.Printf("a\t%v\n", a) fmt.Printf("b\t%v\n", b) }
Các câu hỏi thường gặp về Golang cơ bản
Cú pháp Go có giống C++ không?
Cú pháp: Cú pháp của Go đơn giản hơn nhiều so với C++. một ví dụ như khi muốn đảm bảo an toàn Bộ nhớ: Go tự động hóa quá trình dọn dẹp dữ liệu không cần thiết. Trong khi đó, bạn phải hoàn toàn làm thủ công các quá trình này bằng cách sử dụng con trỏ trong C++.
Cú pháp Go có giống Python không?
Python dễ đọc hơn nhưng sẽ khá dài dòng so với Go. Go sẽ dễ học dễ bắt đầu khi mới tìm hiểu, nhưng sẽ càng khó dần khi càng đào sâu vào phát triển các tính năng và viết các chương trình phức tạp so với Python có mức độ dễ trung bình và duy trì dần về sau. Go biết điều đó nên nó cũng cung cấp thêm một vài tính năng cú pháp để làm cho việc gỡ lỗi code dễ dàng cho các chương trình phức tạp.
Cú pháp Golang giống với ngôn ngữ nào?
Cú pháp của Go giống với Java và C++. Tương tự như Java, Golang là một ngôn ngữ lập trình đa mô hình, được biên dịch, có kiểu tĩnh và đa dụng. Cú pháp của Go gần giống với ‘C’ vì trình biên dịch của ngôn ngữ được xây dựng trong C.
Kết luận Golang cơ bản
Có thể thấy rằng Go mượn các yếu tố quen thuộc từ các ngôn ngữ như C và Python, Go cũng giới thiệu những cải tiến giúp đơn giản hóa và tối ưu hóa việc lập trình và nâng cao độ tin cậy của code. Cú pháp của Go nhấn mạnh sự rõ ràng và hiệu quả, giúp giảm thiểu lỗi lập trình và làm cho ngôn ngữ này dễ tiếp cận hơn với người mới.
Đọc thêm: Học Golang đầy đủ chỉ với 9 bước