Hằng số trong Go

Trong hướng dẫn này, chúng ta sẽ tìm hiểu về hằng số là gì, cách khai báo hằng số, hằng số chuỗi, hằng số boolean, ... trong Go.

Hằng số là gì?

Thuật ngữ hằng số (constant) trong Go được sử dụng để biểu thị các giá trị cố định như:

95  
"I love Go" 
67.89  

Khai báo một hằng số

Từ khóa const được sử dụng để khai báo một hằng số. Hãy xem cách khai báo một hằng bằng một ví dụ.

package main

import (  
    "fmt"
)

func main() {  
    const a = 50
    fmt.Println(a)
}

Chạy chương trình trong Playground

Trong đoạn mã trên a là một hằng số và nó được gán giá trị là 50.

Khai báo một nhóm hằng số

Cũng có một cú pháp khác để định nghĩa một nhóm hằng số bằng cách sử dụng một câu lệnh duy nhất. Dưới đây là một ví dụ để định nghĩa một nhóm hằng số bằng cú pháp này.

package main

import (  
    "fmt"
)

func main() {  
    const (
        name = "John"
        age = 50
        country = "Canada"
    )
    fmt.Println(name)
    fmt.Println(age)
    fmt.Println(country)

}

Chạy chương trình trong Playground

Trong chương trình trên, chúng ta đã khai báo 3 hằng số là name, agecountry. Chương trình trên in ra kết quả sau:

John  
50  
Canada  

Các hằng số, như tên gọi của nó, không thể gán lại bất kỳ giá trị nào khác cho nó. Trong chương trình dưới đây, chúng ta đang cố gắng gán một giá trị mới là 89 cho hằng số a. Điều này không được phép vì a là một hằng số. Chương trình này sẽ báo lỗi biên dịch cannot assign to a.

package main

func main() {  
    const a = 55 //allowed
    a = 89 //reassignment not allowed
}

Chạy chương trình trong Playground

Giá trị của một hằng số phải được biết tại thời điểm biên dịch. Do đó, nó không thể được gán cho một giá trị được trả về bởi một lệnh gọi function vì lệnh gọi function diễn ra tại thời điểm chạy.

package main

import (  
    "math"
)

func main() {  
    var a = math.Sqrt(4)   //allowed
    const b = math.Sqrt(4) //not allowed
}

Chạy chương trình trong Playground

Trong chương trình trên, a là một biến và do đó nó có thể được gán bởi kết quả của function math.Sqrt(4) (Chúng ta sẽ thảo luận về function chi tiết hơn trong một hướng dẫn riêng).

b là một hằng số và giá trị của b cần được biết tại thời điểm biên dịch. Function math.Sqrt(4) sẽ chỉ được thực thi trong thời gian chạy và do đó const b = math.Sqrt(4) không thể biên dịch do bị lỗi:

./prog.go:9:8: const initializer math.Sqrt(4) is not a constant

Hằng số chuỗi, hằng số được định kiểu và không định kiểu

Bất kỳ giá trị nào được đặt giữa dấu ngoặc kép là một hằng chuỗi trong Go. Ví dụ, các chuỗi như "Hello World", "Sam" là các hằng số trong Go.

Hằng số chuỗi thuộc kiểu gì? Câu trả lời là chúng không kiểu.

Một hằng chuỗi như "Hello World" không có bất kỳ kiểu nào.

const hello = "Hello World"  

Trong dòng mã trên, hằng số hello không có kiểu.

Go là một ngôn ngữ được định kiểu mạnh. Tất cả các biến yêu cầu một kiểu rõ ràng. Chương trình gán một biến name cho hằng số không định kiểu n hoạt động như thế nào?

package main

import (  
    "fmt"
)

func main() {  
    const n = "Sam"
    var name = n
    fmt.Printf("type %T value %v", name, name)

}

Chạy chương trình trong Playground

Câu trả lời là hằng số không định kiểu có một kiểu mặc định được liên kết với chúng và chúng cung cấp nó khi và chỉ khi một dòng mã yêu cầu nó. Trong câu lệnh var name = n ở dòng số 8, biến name cần một kiểu và nó lấy nó từ kiểu mặc định của hằng chuỗi n là một string.

Có cách nào để tạo một hằng số được định kiểu không? Câu trả lời là . Đoạn mã sau tạo một hằng số được định kiểu.

const typedhello string = "Hello World"  

typedhello trong đoạn mã trên là một hằng số kiểu string.

Go là một ngôn ngữ được định kiểu mạnh. Không được phép kết hợp các kiểu trong quá trình gán giá trị. Hãy xem điều này có nghĩa là gì với sự trợ giúp của một chương trình.

package main

func main() {  
        var defaultName = "Sam" //allowed
        type myString string
        var customName myString = "Sam" //allowed
        customName = defaultName //not allowed

}

Chạy chương trình trong Playground

Trong đoạn mã trên, trước tiên chúng ta tạo một biến defaultName và gán cho nó hằng số chuỗi Sam. Kiểu mặc định của hằng số chuỗi Sam kiểu string, vì vậy sau khi gán thì biến defaultName là kiểu string.

Trong dòng tiếp theo, chúng ta tạo một kiểu mới myString là bí danh của kiểu string.

Sau đó, chúng ta tạo một biến customName kiểu myString và gán hằng số chuỗi Sam cho nó. Vì hằng số Sam không được định kiểu nên nó có thể được gán cho bất kỳ biến kiểu string nào. Do đó, phép gán này được cho phép và biến customName nhận được kiểu myString.

Bây giờ chúng ta có một biến defaultName kiểu string và một biến customName kiểu myString. Mặc dù chúng ta biết rằng myString là một bí danh của string, chính sách định kiểu mạnh của Go không cho phép các biến của một kiểu được gán cho một kiểu khác.

Do đó không được thực hiện phép gán customName = defaultName và trình biên dịch sẽ báo lỗi:

./prog.go:7:20: cannot use defaultName (type string) as type myString in assignment

Hằng số Boolean

Hằng số boolean không khác gì hằng số chuỗi. Chúng là hai hằng số không định kiểu là truefalse. Các quy tắc tương tự cho hằng số chuỗi áp dụng cho hằng số boolean, vì vậy chúng ta sẽ không lặp lại chúng ở đây. Sau đây là một chương trình đơn giản để giải thích hằng số boolean.

package main

func main() {  
    const trueConst = true
    type myBool bool
    var defaultBool = trueConst //allowed
    var customBool myBool = trueConst //allowed
    defaultBool = customBool //not allowed
}

Chạy chương trình trong Playground

Hằng số

Hằng số bao gồm số nguyên, số thực và hằng số phức. Có một số điều tinh tế trong các hằng số.

Hãy xem ví dụ sau để làm rõ mọi thứ.

package main

import (  
    "fmt"
)

func main() {  
    const a = 5
    var intVar int = a
    var int32Var int32 = a
    var float64Var float64 = a
    var complex64Var complex64 = a
    fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}

Chạy chương trình trong Playground

Trong chương trình trên, hằng số a là không định kiểu và có một giá trị là 5. Bạn có thể tự hỏi kiểu mặc định của a là gì và nếu có thì làm cách nào để gán nó cho các biến thuộc các kiểu khác nhau. Câu trả lời nằm trong cú pháp của a. Chương trình sau đây sẽ làm cho mọi thứ rõ ràng hơn.

package main

import (  
    "fmt"
)

func main() {  
    var i = 5
    var f = 5.6
    var c = 5 + 6i
    fmt.Printf("i's type is %T, f's type is %T, c's type is %T", i, f, c)

}

Chạy chương trình trong Playground

Trong chương trình trên, kiểu của mỗi biến được xác định bởi cú pháp của hằng số. 5 là số nguyên theo cú pháp, 5.6 là số thực và 5 + 6i là số phức theo cú pháp. Khi chương trình trên được chạy, nó sẽ in ra kết quả sau:

i's type is int, f's type is float64, c's type is complex128  

Với kiến ​​thức này, chúng ta hãy thử tìm hiểu cách thức hoạt động của chương trình dưới đây.

package main

import (  
    "fmt"
)

func main() {  
    const a = 5
    var intVar int = a
    var int32Var int32 = a
    var float64Var float64 = a
    var complex64Var complex64 = a
    fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}

Chạy chương trình trong Playground

Trong chương trình trên, giá trị của hằng số a5 và cú pháp của a là chung. Nó có thể đại diện cho một số thực, số nguyên hoặc thậm chí là một số phức không có phần ảo. Do đó, nó có thể được gán cho bất kỳ kiểu tương thích nào.

Kiểu mặc định của các loại hằng số này có thể được coi là được tạo nhanh chóng tùy thuộc vào ngữ cảnh. var intVar int = a yêu cầu a phải là số nguyên để nó trở thành một hằng số int. var complex64Var complex64 = a yêu cầu a phải là một số phức và do đó nó trở thành một hằng số phức. Khá gọn gàng :).

Biểu thức số

Các hằng số tự do được trộn và so khớp trong các biểu thức và một kiểu chỉ cần thiết khi chúng được gán cho các biến hoặc được sử dụng ở bất kỳ vị trí nào trong mã yêu cầu một kiểu.

package main

import (  
    "fmt"
)

func main() {  
    var a = 5.9 / 8
    fmt.Printf("a's type is %T and value is %v", a, a)
}

Chạy chương trình trong Playground

Trong chương trình trên, 5.9 là một số thực theo cú pháp và 8 là một số nguyên theo cú pháp. Tuy nhiên, 5.9/8 vẫn được phép vì cả hai đều là hằng số. Kết quả của phép chia là 0,7375 là một số thực và do đó biến a là kiểu float. Đầu ra của chương trình là

a's type is float64 and value is 0.7375  

Trong hướng dẫn tiếp theo, chúng ta sẽ tìm hiểu về function (hàm) trong Go:

Function trong Go
Trong hướng dẫn này, chúng ta sẽ tìm hiểu function là gì, cách khai báo function, tham số đầu vào, kiểu dữ liệu trả về, ... của function trong Go.

Cảm ơn bạn đã đọc. Vui lòng chia sẻ phản hồi và nhận xét có giá trị của bạn.

Nếu Comdy hữu ích và giúp bạn tiết kiệm thời gian làm việc

Bạn có thể vui lòng đưa Comdy vào whitelist của trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi trong việc trả tiền cho dịch vụ lưu trữ web để duy trì hoạt động của trang web.

Go
Bài Viết Liên Quan:
Phương thức (method) trong Go
Trung Nguyen 02/12/2021
Phương thức (method) trong Go

Trong hướng dẫn này, chúng ta sẽ tìm hiểu phương thức (method) trong Go là gì? Cú pháp khai báo phương thức, so sánh phương thức với hàm, ... trong Go.

Struct trong Go
Trung Nguyen 28/11/2021
Struct trong Go

Trong hướng dẫn này, chúng ta sẽ tìm hiểu struct là gì, cách khai báo và sử dụng một struct trong Go, struct ẩn danh, so sanh hai struct, ...

Con trỏ trong Go
Trung Nguyen 28/11/2021
Con trỏ trong Go

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách con trỏ (pointer) hoạt động trong Go và nó khác với con trỏ trong các ngôn ngữ khác như C và C++ như thế nào.

Chuỗi trong Go
Trung Nguyen 28/11/2021
Chuỗi trong Go

Chuỗi (string) xứng đáng được đề cập đặc biệt trong Go vì chúng khác biệt trong cách triển khai khi so sánh với các ngôn ngữ khác.