Các Thành Phần Cơ Bản Trong Go

467

Bài viết được sự cho phép của tác giả Võ Xuân Phong

Biến và giá trị trong Golang

Các biến (variables) trong Go phải được xác định và định nghĩa rõ ràng.

Từ khóa “var” trong Go dùng để khai báo một hoặc nhiều biến, và khi khai báo biến phải có tên biến và kiểu dữ liệu của biến một cách rõ ràng.

  Channel trong Golang là gì? So sánh Callback function và mutex lock với channel
  Chiến trường sinh tử phiên bản lập trình : Python vs Ruby vs Golang

Có các kiểu khai báo biến và gán giá trị như sau:

package main

import "fmt"

func main(){
//var [tên biến] = [giá trị]
var a = true
fmt.Printf("a=%t\n", a)
//[tên biến] := [giá trị]
b := "good bye"
fmt.Printf("b=%s\n", b)
//var [tên biến 1], [tên biến 2] [kiểu giá trị] = [giá trị]
var c, d int = 1 ,2
fmt.Printf("c=%d\nd=%d\n", c, d)
//var [tên biến] [kiểu giá trị]
//[tên biến] = [giá trị]
var e float32
e = 10.5
fmt.Printf("e=%f\n",e)
fmt.Scanf("Pause")
}

Output: (Run Code)

a=true
b=good bye
c=1
d=2
e=10.500000

Hằng số trong Golang

Hằng số là một giá trị cố định và không thay đổi. Cũng như các ngôn ngữ lập trình khác để khai báo hằng số trong Go chúng ta sử dụng từ khóa const. Go hỗ trợ hằng số cho ký tự (character), chuỗi (string), kiểu bool (boolean), và các giá trị số (numeric values).

Từ khóa const có thể khai báo ở bất cứ đâu mà từ khóa var có thể.

package main

import "fmt"

const hello string = "Hello World"

func main(){
fmt.Printf("hello=%s\n", hello)
const n = 100
nx2 := n*2
fmt.Printf("n=%d\n", n)
fmt.Printf("nx2=%d\n", nx2)
fmt.Scanf("Pause")
}

Output (Run Code):

hello=Hello World
n=100
nx2=200

Vòng lặp For trong Golang

Go cũng có vòng lặp For nhưng không có vòng lặp While, chúng ta có thể sử dụng cú pháp của vòng lặp For để thay thế cho While.

package main

import "fmt"

func main(){
fmt.Println("Go does not have While loop we should use For instead:")
i:=5
for i > 0{
fmt.Printf("%d\t",i)
i--
}
fmt.Println("\nBreak out of the loop:")
for {
fmt.Printf("loop \t")
break
}
fmt.Println("\nContinue to the next iteration of the loop:")
for n := 0; n <= 5; n++ {
if n%2 == 0 {
continue
}
fmt.Printf("%d\t",n)
}
fmt.Scanf("Pause")
}

Output (Run Code):

Go does not have While loop we should use for instead:
5 4 3 2 1
Break out of the loop:
loop
Continue to the next iteration of the loop:

1 3 5

Câu lệnh điều khiển If/Else trong Golang

If/Else trong Golang có 1 điểm đặc biệt là có thêm sự ngắn gọn, chúng ta có thể gán giá trị hoặc lấy giá trị từ một hàm nào đó trên cú pháp của lệnh If.

package main

import (
"bufio"
"fmt"
"math/rand"
"os"
)

var (
PASSWORD = "123456"
)

func getRandNumber(n int) int {
return rand.Intn(n)
}

func main() {
var password string

scanner := bufio.NewScanner(os.Stdin)

fmt.Print("Enter your password:")
for scanner.Scan() {
password = scanner.Text()
break
}

if password == PASSWORD {
fmt.Printf("Your password is correct\n")
} else {
fmt.Printf("Your password is incorrect\n")
}

//Call a function get assign value to num variable.
if num := getRandNumber(20); num < 19 { fmt.Printf("number %d is smaller than 19\n", num) } if num := getRandNumber(20); num > 10 {
fmt.Printf("number %d is greater than 10", num)
} else if num < 10 {
fmt.Printf("number %d is smaller than 10", num)
} else {
fmt.Printf("number %d is equal to 10", num)
}
fmt.Scanf("Pause")
}

Output (Run Code):

Enter your password:123456
Your password is correct
number 1 is smaller than 19
number 7 is smaller than 10

Switch Case trong Golang

Chúng ta có thể sử dụng nhiều điều kiện trong một case bằng dấu phẩy như ví dụ 1 bên dưới. Và chúng ta cũng có thể sử dụng switch như câu lệnh If/Else như ví dụ 2, và cũng giống như câu lệnh điều khiển If/Else Go cho phép ta gán hoặc gọi hàm để gán giá trị cho biến tại switch, như ví dụ 3.

package main

import (
"bufio"
"fmt"
"os"
)

func main() {
var say string

scanner := bufio.NewScanner(os.Stdin)

fmt.Print("Say something:")
for scanner.Scan() {
say = scanner.Text()
break
}
// 1. We can use commas for multiple expressions in the same case
switch say {
case "hello", "hi":
fmt.Println("Greetings")
case "good bye":
fmt.Println("Bye")
default:
fmt.Println("Unknow")
}

// 2. Switch without an expression
x := 10
switch {
case x < 10: fmt.Println("x is smaller than 10") case x > 10:
fmt.Println("x is greater than 10")
default:
fmt.Println("x is equal to 10")
}

// 3. Assign a value in the expression of switch
whatIsMyType := func(i interface{}) {
switch t := i.(type) {
case string:
fmt.Println("You are a string")
case int:
fmt.Println("You are an integer value")
default:
fmt.Printf("Your are %T", t)
}
}

whatIsMyType("Hello World")
whatIsMyType(1000)
whatIsMyType(true)

fmt.Scanf("Pause")
}

Output (Run Code):

Say something:hello
Greetings
x is equal to 10
You are a string
You are an integer value
Your are bool

Hàm (Functions) trong Golang

Để khai báo một hàm ta dùng từ khóa “func”.

Cách 1: Hàm với giá trị trả về

func [tên Hàm]([tên biến 1] [kiểu biến], [tên biến 2] [kiểu biến]) [kiểu trả về]{

     //thân hàm…

}

Cách 2: Hàm rút gọn kiểu biến nếu các kiểu của biến đều cùng chung kiểu

func [tên Hàm]([tên biến 1],  [tên biến 2] [kiểu biến]) [kiểu trả về]{

     //thân hàm…

}

package main

import "fmt"

//Chu vi hình chữ nhật
//Rectangle Perimeter
//Cách khai báo 1
func rectPerimeter(a int, b int) int {
return (a + b) * 2
}

//Diện tích hình chữ nhật
//Rectangle Area
//Cách khai báo 2
func rectArea(a, b int) int {
return a * b
}

func main() {
a := 2
b := 3
rectPeri := rectPerimeter(a, b)
fmt.Printf("Perimeter of rectangle is %d\n", rectPeri)
rectAr := rectArea(a, b)
fmt.Printf("Area of rectangle is %d\n", rectAr)
fmt.Scanf("Pause")
}

Output(Run Code):

Perimeter of rectangle is 10
Area of rectangle is 6

Hàm trả về nhiều giá trị (Multiple Return Values) trong Golang.

Hàm trả về nhiều giá trị trong Golang có các cách viết sau

Cách 1: Hàm với giá trị trả về

func [tên Hàm]([tên biến 1] , [tên biến 2] [kiểu biến]) ([kiểu trả về 1], [kiểu trả về 2]){

            //thân hàm…

           //logic tính toán…

            return [giá trị trả về 1], [giá trị trả về 2]

}

Cách 2: Hàm khai bào trước tên của giá trị trả về, nếu đã khai báo trước giá trị trả về thì chỉ cần có return mà không cần phải bỏ các giá trị bên cạnh từ khóa return

func [tên Hàm]([tên biến truyền vào 1] , [tên biến truyền vào 2] [kiểu biến truyền vào]) ([tên biến trả về 1] [kiểu trả về 1], [tên biến trả về 2][kiểu trả về 2]){

             //thân hàm…

            //logic tính toán…

            return

}

Cách 3: Hàm khai báo trước tên giá trị trả về với cách viết rút gọn kiểu trả về nếu tất cả các giá trị trả về cùng kiểu.

func [tên Hàm]([tên biến truyền vào 1] , [tên biến truyền vào 2] [kiểu biến truyền vào]) ([tên biến trả về 1],  [tên biến trả về 2][kiểu trả về]){

            //thân hàm…

           //logic tính toán…

            return

}

package main

import "fmt"

//Chu vi hình chữ nhật
//Rectangle Perimeter
func rectPerimeter(a int, b int) int {
return (a + b) * 2
}

//Diện tích hình chữ nhật
//Rectangle Area
func rectArea(a, b int) int {
return a * b
}

//Chu vi và diện tích hình chữ nhật cách 1
func rectPeriAndArea1(a, b int) (int, int) {
rectPeri := rectPerimeter(a, b)
rectArea := rectArea(a, b)
return rectPeri, rectArea
}

//Chu vi và diện tích hình chữ nhật cách 2
func rectPeriAndArea2(a, b int) (rectPeri int, rectAr int) {
rectPeri = rectPerimeter(a, b)
rectAr = rectArea(a, b)
return
}

//Chu vi và diện tích hình chữ nhật cách 3
func rectPeriAndArea3(a, b int) (rectPeri, rectAr int) {
rectPeri = rectPerimeter(a, b)
rectAr = rectArea(a, b)
return
}

func main() {
a := 2
b := 3
rectPeri1, rectAr1 := rectPeriAndArea1(a, b)
fmt.Printf("rectPeri1=%d, rectAr1=%d\n", rectPeri1, rectAr1)
rectPeri2, rectAr2 := rectPeriAndArea2(a, b)
fmt.Printf("rectPeri2=%d, rectAr2=%d\n", rectPeri2, rectAr2)
rectPeri3, rectAr3 := rectPeriAndArea3(a, b)
fmt.Printf("rectPeri3=%d, rectAr3=%d\n", rectPeri3, rectAr3)
fmt.Scanf("Pause")
}

Output(Run Code):

rectPeri1=10, rectAr1=6
rectPeri2=10, rectAr2=6
rectPeri3=10, rectAr3=6

Hàm bất định (Variadict Function) trong Golang.

Hàm bất định (Variadict Function) là một hàm chấp nhận số lượng đối số khác nhau và không biết trước.

Chúng ta có thể thấy có dấu … ngộ ha. Nhưng nó có ý nghĩa để khai báo số phần tử không biết trước của đối số truyền vào hàm.

Hàm này cũng nhận giá trị là một array nhưng sau array này lại có dấu … vậy nó có ý nghĩa là gì nhỉ? Dấu … này sẽ tự động phân tách các phần tử tròng mảng thành các đối số vào hàm.

Ví dụ:

myArray    = [1,2,3,4]

myArray… = 1,2,3,4

package main

import "fmt"

func min(numbers ...int) int {
result := numbers[0]
for _, num := range numbers {
if result > num {
result = num
}
}
return result
}

func main() {
fmt.Printf("min of 5,3,2 is %d\n", min(5, 3, 2))
fmt.Printf("min of 5,3,2,1 is %d\n", min(5, 3, 2, 1))
numbers := []int{5, 3, 2, 1, 0}
fmt.Printf("min of array [5,3,2,1,0] is %d", min(numbers...))
fmt.Scanf("Pause")
}

Output(Run Code):

min of 5,3,2 is 2
min of 5,3,2,1 is 1
min of array [5,3,2,1,0] is 0

Bài viết gốc được đăng tải tại anhlamweb.com

Có thể bạn quan tâm:

Xem thêm các việc làm Developer hấp dẫn tại TopDev