Go part 2
Bài đăng này đã không được cập nhật trong 3 năm
Packages
Tất cả các chương trình của Go đều được tổ chức các files lại với nhau thành một nhóm được gọi là packages, do đó code có thể được tái sử dụng, được include vào trong project khác Ví dụ về package http trong thư viện của Go
net/http/
cgi/
cookiejar/
testdata/
fcgi/
httptest/
httputil/
pprof/
testdata/
Main packages
Main packages có ý nghĩa đặc biệt trong Go, Tất cả các chương trình bạn xây dựng trong Go đều phải có package main này.
Khi trình biên dịch thấy main package này, thì nó cũng đồng thời phải tìm ra một phương thức main()
,
nếu phương thức này không được tìm thấy thì binary executable
sẽ không được tạo ra,
Phương thức main()
này là điểm bắt đầu của chương trình và nếu không có nó thì chương trình sẽ không có điểm chạy đầu hay nói cách khác là nó không biết chạy bắt đầu từ đâu.
import
Câu lệnh import này nói cho trình biên dịch biết nơi nào trên cần tìm package muốn import. Khi bạn sử dụng từ khoá import tức là bạn đã nói cho trình biên dịch biết bạn muốn tham chiếu code nằm trong package nếu bạn cần phải import nhiều package thì có thể sử dụng import kiểu block
import (
"fmt"
"strings"
)
Những packages này được tìm thấy trên ổ đĩa, dựa vào đường dẫn tương đối tới thực mục được tham chiếu bởi Go environment. Những package ở trong standard lib được đặt ở nơi mà Go đã cài đặt trên máy.
giả sử Go được cài đặt ở /usr/local/go và GOPATH được set /home/project:/home/mybraries
thì trình biên dịch sẽ tìm gói net/http
theo thứ tự sau:
/usr/local/go/src/pkg/net/http
/home/myproject/src/net/http
/home/mylibraries/src/net/http
Nếu theo thứ tự trên mà trình biên dịch không tìm ra thì sẽ thông báo lỗi.
ngoài ra bạn cũng có thể imort một package từ trên internet (remote import)
import "github.com/account_name/package"
Khi import một path có chứa url, Go tooling sẽ fetch package từ DVCS(distributed version control systems ) và đưa code đó vào GOPATH
bằng câu lệnh go get
,
go get
sẽ lấy bất cứ một url hoặc có thể được dùng để load các gói dependence.
Bạn cũng có thể đặt tên cho các gói được import ví dụ
package main
import (
"fmt"
myfmt "mylib/fmt"
)
func main() {
fmt.Println("Standard Library")
myfmt.Println("mylib/fmt")
}
Trình biên dịch của Go sẽ build fail và trả về error nếu bạn import package mà bạn ko dùng đến nó.
init
Mỗi package có thể có nhiều các init function được gọi tại thời điểm bắt đầu thực thi, tất cả các init function này sẽ được trình biên dịch lên schedule để chạy init function thích hợp cho việc setup package khởi tạo các biến hay thực thi một số tác vụ nào đó trước khi chạy vào phần chính của chương trình.
package postgres
import (
"database/sql"
)
func init() {
sql.Register("postgres", new(PostgresDriver))
}
Go tool
bạn có thể gõ go
trên terminal để xem list tool của go
Build go file bằng câu lệnh
go build hello.go
Sẽ sinh ra một file build tên hello
Để clean file này đi dùng lệnh
go clean go clean hello.go
Để thực thi một chương trình bạn có thể run file đã build hoặc run trực tiếp bằng câu lệnh sau
go run hello.go
go run
sẽ thực thi cả 2 việc build và thực thi chương trình sau khi đã build.
go vet
Câu lệnh này được dùng để check các lỗi thông thường như, nó cũng giống như câu lệnh ruby -c filename.rb
trong ruby
- Sai parameter
- Tên của method không đúng quy tắc
- Các tags không đúng struct
giả sử tôi sẽ xóa chữ
p
ở package đi và run code
go vet hello.go
kết quả là
\can't load package: package main:
test.go:1:1: expected 'package', found 'IDENT' ackage
go format
go format là một chức năng khá hay được nhiều người sử dụng cho việc format code như space, indent làm cho code của bạn dễ nhìn hơn ...
package main
import "fmt"
func main() { fmt.Println("Hello, World!")
}
gải sử hàm main tôi để code trên dấu ngoặc xoắn sau khi sử dụng lệnh
gofmt -w hello.go
code trong file hello.go sẽ được format gọn gàng dễ đọc lại như sau
func main() {
fmt.Println("Hello, World!")
}
Array
Array trong Go là kiểu dữ liệu fixed-length, nó chứa các element của cùng một kiểu dữ liệu liên tiếp nhau, kiểu dữ liệu có thể là kiểu nguyên thuỷ buil-in như integer, string hay struct. Các thành phần trong mảng kết nối với nhau thành một chuỗi liên tiếp và các element này phải cùng một kiểu dữ liệu và ta có thể access vào mảng thông qua vị trí của index.
Khai báo một mảng kiểu integer
var array [5]int
Mỗi một khi được khai báo thì cả về kiểu dữ liệu và độ dài của mảng sẽ không thể được thay đổi nữa. Nếu muốn có nhiều element hơn nữa thì bạn phải tạo thêm một mảng mới và copy value của nó sang. Khi một mảng được khởi tạo thì giá trị mặc định của nó sẽ là 0. Bạn có thể thấy nó khác với ruby, đối với ruby thì khi khai báo ta không cần khai báo kiểu và độ dài mảng. Thêm nữa là kiểu dữ liệu của các phần tử mảng không cần phải giống nhau.
Thao tác với mảng
Đối với mảng trong Go thì nó rất nhanh và hiệu quả bởi bộ nhớ của nó được bố trí một cách có trình tự, rất hiệu quả trong việc access vào một element cụ thể (dự là nhanh hơn ruby :v)
Để truy cập vào một element ta sử dụng toán tử []
array := [5]int{1,2,3,4,5}
array[2] # 3
Bạn có thể khai báo một mảng kiểu con trỏ (pointer)
array := [5]*int{0: new(int), 1: new(int)}
#gán giá trị cho mảng
*array[0] = 10
*array[1] = 20
và mảng sau khi được gán sẽ như sau:
Một mảng có thể gán bằng các mảng khác có cùng kiểu dữ liệu
var arr := [5]string
var arr2:= [5]string{0: “Red”, 1: “Blue”, “Green”, “Yellow”, “Pink”}
arr = arr2 # copy arr2 sang arr
Chú ý là chỉ khi 2 mảng được khai báo cùng kiểu cùng độ dài mới được gán cho nhau nếu không sẽ có lỗi sinh ra trong quá trình biên dịch
Gán một mảng pointer sang mảng pointer khác
var array1 [3]string
var array2 := [3]*string{new(string), new(string), new(string)}
*array[0]= ”Red”
*array[1]= ”Blue”
*array[2]= “Green”
# gán mảng pointer
array1 = array2
Như trên ta có 2 mảng pointer cùng trỏ tới cùng một string ở mỗi element. Điều đó có nghĩa là bạn chỉ copy giá trị con trỏ chứ không copy giá trị mà con trỏ trỏ tới.
Mảng đa chiều
Bạn có thể sử dụng mảng 2 chiều cho mục đích khác nhau như quan hệ cha con … Khai báo mảng 2 chiều:
var array [4][2]int
array := [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
array := [4][2]int{1: {20, 21}, 3: {40, 41}}
array := [4][2]int{1: {0: 20}, 3: {1: 41}}
Tham khảo
Go in action https://livebook.manning.com/#!/book/go-in-action/chapter-1/
All rights reserved