Kiểu dữ liệu cơ bản và toán tử trong Go

1. Số thực dấu phẩy động (Floating-point)

Tổng quan

  • Kiểu số thực được dùng để lưu trữ các giá trị có phần thập phân.
  • Có thể gán một số nguyên cho biến kiểu số thực, nhưng không thể gán ngược lại.
  • Kết quả của phép toán trên số thực luôn là số thực.
  • Go cung cấp hai loại: float32float64.

Phạm vi giá trị

KiểuGiá trị tối đa
float323.40e+38
float641.798e+308

Để lấy nhanh các giá trị này, có thể sử dụng hằng số trong gói math:

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println(math.MaxFloat32)
    fmt.Println(math.MaxFloat64)
}

Phép toán trên số thực

  • float32float64 không thể tính trực tiếp với nhau, cần ép kiểu.
package main

import "fmt"

func main() {
    var x float32 = 2.5
    var y float64 = 4.1
    fmt.Println(x + float32(y))
    fmt.Println(float64(x) + y)
}
  • Nên ưu tiên dùng float64 vì tuy tốn bộ nhớ hơn, nhưng float32 dễ gây sai số khi tính toán nhiều.
  • Phép toán giữa hai số nguyên cho kết quả là số nguyên, giữa hai số thực cho kết quả là số thực.
package main

import "fmt"

func main() {
    var m, n int = 5, 2
    var p, q float64 = 7, 3
    fmt.Println(m / n)
    fmt.Println(p / q)
}

2. Kiểu Boolean

Giới thiệu

  • Từ khóa: bool.
  • Chỉ có hai giá trị: true (đúng, tương ứng với 1 trong nhị phân) và false (sai, tương ứng với 0).
  • Không thể ép kiểu giữa bool và các kiểu khác.
  • Kích thước: 1 byte.
  • Thường dùng trong các câu lệnh điều kiện.

Ví dụ

Khai báo biến bool:

package main

import "fmt"

func main() {
    var flag1 bool = true
    var flag2 bool = false
    var flag3 = true
    flag4 := false
    fmt.Println(flag1, flag2, flag3, flag4)
}

Sử dụng unsafe.Sizeof() để kiểm tra kích thước:

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    val := false
    fmt.Println(unsafe.Sizeof(val))
}

Mặc dù bool chiếm 1 byte, nhưng không thể ép kiểu sang int8 hay byte:

package main

import "fmt"

func main() {
    var a int8 = 1
    var b byte = 0
    var c bool = false
    fmt.Println(a, b, c)
    // Các dòng sau sẽ báo lỗi
    // a = int8(c)
    // b = byte(c)
    // c = bool(a)
    // c = bool(b)
    b = byte(a) // Hợp lệ
}

Biến bool có thể nhận giá trị từ biểu thức so sánh hoặc logic.

3. Toán tử

Tổng quan

Go hỗ trợ nhiều loại toán tử: số học, so sánh, logic, gán, quan hệ, bit. Cần chú ý thứ tự ưu tiên khi kết hợp.

Toán tử số học

Toán tửÝ nghĩa
+Cộng
-Trừ
*Nhân
/Chia
%Chia lấy dư
++Tăng 1
--Giảm 1

Toán tử so sánh

Toán tửÝ nghĩa
==Bằng nhau
!=Khác nhau
>Lớn hơn
<Nhỏ hơn
>=Lớn hơn hoặc bằng
<=Nhỏ hơn hoặc bằng

Toán tử logic

Toán tửÝ nghĩa
!Phủ định
&&Và (cả hai đều đúng)
||Hoặc (một trong hai đúng)

Toán tử gán

Toán tửÝ nghĩa
=Gán giá trị
+=Cộng và gán
-=Trừ và gán
*=Nhân và gán
/=Chia và gán
%=Chia lấy dư và gán
<<=Dịch trái và gán
>>=Dịch phải và gán
&=AND bit và gán
|=OR bit và gán
^=XOR bit và gán

4. Toán tử bit

Khái niệm cơ bản: Mã nguồn, mã đảo, mã bù

  • Với số dương, cả ba loại mã đều giống giá trị nhị phân gốc.
  • Với số âm:
    • Mã nguồn: biểu diễn nhị phân của giá trị tuyệt đối.
    • Mã đảo: đảo tất cả các bit của mã nguồn.
    • Mã bù: mã đảo cộng thêm 1. Đây là cách máy tính lưu trữ số âm.

Toán tử bit trong Go

Toán tửÝ nghĩa
<<Dịch trái
>>Dịch phải
|OR: bit nào là 1 thì kết quả là 1
&AND: cả hai đều là 1 mới cho kết quả 1
^XOR: giống nhau là 0, khác nhau là 1
&^AND NOT: nếu bit bên phải là 0 thì giữ nguyên bên trái, nếu là 1 thì xóa về 0

5. Chuỗi (String)

Tổng quan

  • Chuỗi là một dãy ký tự bất biến. Có thể chứa chữ, số, ký tự đặc biệt, nhưng chuỗi số không thể dùng trong phép tính toán.
  • Từ khóa: string.
var msg string = "hello"
name := "world"
  • Giá trị chuỗi được đặt trong dấu ngoặc kép "". Nếu dùng dấu backtick ``, nội dung sẽ được giữ nguyên định dạng (kể cả ký tự đặc biệt).
a := "line1\nline2"
b := `line1\nline2`
fmt.Println(a) // In: line1 (xuống dòng) line2
fmt.Println(b) // In: line1\nline2

Chuyển đổi giữa chuỗi và số

Gói strconv cung cấp các hàm hỗ trợ chuyển đổi.

Chuỗi sang số nguyên

package main

import (
    "fmt"
    "strconv"
)

func main() {
    s := "42"
    // ParseInt(chuỗi, cơ số, kích thước bit)
    i, _ := strconv.ParseInt(s, 10, 64)
    fmt.Println(i)
    fmt.Printf("%T\n", i)

    // Cách viết ngắn gọn: Atoi (tương đương ParseInt với cơ số 10 và kích thước 64)
    j, _ := strconv.Atoi(s)
    fmt.Println(j)
}

Số nguyên sang chuỗi

package main

import (
    "fmt"
    "strconv"
)

func main() {
    num := 42
    // FormatInt(số int64, cơ số)
    s := strconv.FormatInt(int64(num), 10)
    fmt.Println(s)
    fmt.Printf("%T\n", s)

    // Cách thông dụng: Itoa (tương đương FormatInt với cơ số 10)
    s2 := strconv.Itoa(num)
    fmt.Println(s2)
}

Chuỗi sang số thực

package main

import (
    "fmt"
    "strconv"
)

func main() {
    s := "3.14"
    // ParseFloat(chuỗi, bitSize: 32 hoặc 64)
    f, _ := strconv.ParseFloat(s, 64)
    fmt.Println(f)
    fmt.Printf("%T\n", f)
}

Số thực sang chuỗi

package main

import (
    "fmt"
    "strconv"
)

func main() {
    val := 2.718
    // FormatFloat(số, định dạng, độ chính xác, bitSize)
    result := strconv.FormatFloat(val, 'f', 3, 64)
    fmt.Println(result)
    fmt.Printf("%T\n", result)
}

Thẻ: Go float32 float64 bool string

Đăng vào ngày 6 tháng 6 lúc 02:29