1 การทำความเข้าใจเกี่ยวกับประเภทข้อมูลของภาษา Go
ใน ภาษา Go, ประเภทข้อมูลเป็นพื้นฐานของการเขียนโปรแกรม และกำหนดรูปแบบของข้อมูลที่ตัวแปรสามารถเก็บไว้ได้ ประเภทข้อมูลพื้นฐานที่ภาษา Go มีคือ
ประเภทข้อมูล | คำอธิบาย | การใช้งานหน่วยความจำ |
---|---|---|
bool | ประเภทบูลีน, ใช้เก็บค่า true หรือ false | 1 ไบต์ |
int, uint | จำนวนเต็มและจำนวนเต็มบวก, ขนาดเริ่มต้นขึ้นอยู่กับแพลตฟอร์มระบบ | 4 หรือ 8 ไบต์ |
int8, uint8 | จำนวนเต็ม 8 บิตและจำนวนเต็มบวก 8 บิต | 1 ไบต์ |
int16, uint16 | จำนวนเต็ม 16 บิตและจำนวนเต็มบวก 16 บิต | 2 ไบต์ |
int32, uint32 | จำนวนเต็ม 32 บิตและจำนวนเต็มบวก 32 บิต | 4 ไบต์ |
int64, uint64 | จำนวนเต็ม 64 บิตและจำนวนเต็มบวก 64 บิต | 8 ไบต์ |
float32 | จำนวนทศนิยม 32 บิต | 4 ไบต์ |
float64 | จำนวนทศนิยม 64 บิต | 8 ไบต์ |
complex64 | จำนวนเชิงซ้อนที่มีส่วนจริงและส่วนจินตภาพ 32 บิต | 8 ไบต์ |
complex128 | จำนวนเชิงซ้อนที่มีส่วนจริงและส่วนจินตภาพ 64 บิต | 16 ไบต์ |
byte | คล้ายกับ uint8 | 1 ไบต์ |
rune | คล้ายกับ int32 แทนรหัส Unicode | 4 ไบต์ |
string | ประเภทข้อมูลสตริง | ขึ้นอยู่กับความยาวของสตริง |
error | อินเตอร์เฟซข้อผิดพลาด, ใช้สำหรับส่งค่าข้อผิดพลาด | ไม่มีขนาดคงที่ |
ประเภทเหล่านี้สามารถถูกเลือกตามความต้องการต่าง ๆ เช่น การคำนวณตัวเลข, การประมวลผลข้อความ, หรือควบคุมตรรกะทางตรรกะ
2 ประเภทข้อมูลจำนวนเต็ม
2.1 ภาพรวมของประเภทข้อมูลจำนวนเต็ม
ภาษา Go มีประเภทข้อมูลจำนวนเต็มที่สร้างมาให้ใช้หลากหลายประเภทดังนี้:
- จำนวนเต็มที่ลงชื่อ:
int8
,int16
,int32
(หรือrune
),int64
, และint
- จำนวนเต็มบวก:
uint8
(หรือbyte
),uint16
,uint32
,uint64
, และuint
ขนาดของ int
และ uint
คือ 4 ไบต์บนระบบ 32 บิต และ 8 ไบต์บนระบบ 64 บิต ช่วงค่าของประเภทข้อมูลจำนวนเต็มแสดงในตารางด้านล่าง:
ประเภท | ช่วงของค่า |
---|---|
int8 | -128 ถึง 127 |
uint8 | 0 ถึง 255 |
int16 | -32768 ถึง 32767 |
uint16 | 0 ถึง 65535 |
int32 | -2147483648 ถึง 2147483647 |
uint32 | 0 ถึง 4294967295 |
int64 | -9223372036854775808 ถึง 9223372036854775807 |
uint64 | 0 ถึง 18446744073709551615 |
2.2 การใช้งานตัวแปรจำนวนเต็ม
รูปแบบพื้นฐานในการประกาศตัวแปรจำนวนเต็มคือดังนี้:
var ชื่อตัวแปร ประเภทข้อมูล = ค่าเริ่มต้น
ตัวอย่างโค้ด:
package main
import "fmt"
func main() {
var a int = 10 // ตัวแปรจำนวนเต็มและลงชื่อ
var b uint = 20 // ตัวแปรจำนวนเต็มบวก
var c int8 = -128 // ค่า int8 ที่เล็กที่สุด
fmt.Println(a, b, c)
}
2.3 การดำเนินการทางคณิตศาสตร์ของจำนวนเต็ม
ภาษา Go รองรับตัวดำเนินการทางคณิตศาสตร์ทั่วไป เช่น การบวก (+
), การลบ (-
), การคูณ (*
), การหาร (/
), และโมดูลัส (%
), ไปจนถึงตัวดำเนินการแบบวิตวี เช่น วิตวี AND (&
), OR (|
), XOR (^
), การสเลิกซ้าย (<<
), และการสเลิกขวา (>>
).
package main
import "fmt"
func main() {
x := 10
y := 3
// ดำเนินการทางคณิตศาสตร์
fmt.Println(x + y) // การบวก
fmt.Println(x - y) // การลบ
fmt.Println(x * y) // การคูณ
fmt.Println(x / y) // การหาร
fmt.Println(x % y) // โมดูลัส
// ดำเนินการทางวิตวี
fmt.Println(x & y) // วิตวี AND
fmt.Println(x | y) // วิตวี OR
fmt.Println(x ^ y) // วิตวี XOR
fmt.Println(x << 1) // การเลิกซ้ายทีละ 1
fmt.Println(x >> 1) // การเลิกขวาทีละ 1
}
3 ประเภทข้อมูลทศนิยมทวิภาค
3.1 ภาพรวมของประเภทข้อมูลจำนวนจริง (Floating Point)
ในภาษา Go, ประเภทข้อมูลที่เป็นจำนวนจริงรวมถึง float32
และ float64
ซึ่งสอดคล้องกับข้อมูลจริงที่มีขนาด 32 บิตและ 64 บิต โดยทั่วไปแล้วแนะนำให้ใช้ float64
เนื่องจากมีช่วงค่าที่กว้างกว่า และมีความแม่นยำมากขึ้น
-
float32
ประมาณ 23 บิตที่สำคัญ มีประมาณ 7 หลักทศนิยม -
float64
ประมาณ 52 บิตที่สำคัญ มีประมาณ 16 หลักทศนิยม
3.2 การใช้งานตัวแปรที่เป็นจำนวนจริง (Floating Point)
ตัวแปรที่เป็นจำนวนจริงสามารถประกาศได้โดยการกำหนดค่าลงตรงหรือใช้คีย์เวิร์ด var
:
package main
import "fmt"
func main() {
var f1 float32 = 3.14 // กำหนดชนิด float32 โดยตรง
f2 := 3.14 // ถูกตรวจสอบอัตโนมัติเป็นชนิด float64
fmt.Println(f1, f2)
}
3.3 การคำนวณแบบจำนวนจริงและปัญหาที่เกิดขึ้น
การคำนวณแบบจำนวนจริงอาจ导致การสูญเสียความแม่นยำ การดำเนินการที่มีความแม่นยำมากมักเป็นปัญหาที่พบบ่อยโดยเฉพาะเมื่อลบจำนวนสองจำนวนที่ใกล้เคียงกันมาก
package main
import "fmt"
func main() {
f1 := .1
f2 := .2
f3 := f1 + f2
fmt.Println(f3) // ผลลัพธ์อาจไม่ได้ .3 ตามที่คาดหวังเนื่องจากปัญหาความแม่นยำ
// แก้ปัญหาความแม่นยำโดยใช้การแสดงผลที่มีรูปแบบ
fmt.Printf("%.1f\n", f3) // ผลลัพธ์ถูกแก้ไขเป็น .3
}
4 ประเภทข้อมูลบูลีน (Boolean)
4.1 ภาพรวมของประเภทข้อมูลบูลีน
บูลีนเป็นประเภทข้อมูลที่ง่ายที่สุด และสามารถมีค่าได้เพียงสองค่า: true
(จริง) และ false
(เท็จ) มันมีบทบาทที่สำคัญมากในคำสั่งเงื่อนไขและโครงสร้างการควบคุมการทำซ้ำ
4.2 การใช้งานตัวแปรบูลีน
การประกาศและใช้งานตัวแปรบูลีน:
package main
import "fmt"
func main() {
var success bool = true
var fail bool = false
fmt.Println("ดำเนินการเสร็จสมบูรณ์:", success)
fmt.Println("ดำเนินการล้มเหลว:", fail)
}
ค่าบูลีนมักถูกใช้ในคำสั่งเงื่อนไข:
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // เท็จ
fmt.Println("a < b:", a < b) // จริง
}
5 ประเภทข้อมูลสตริง (String)
5.1 ภาพรวมของสตริง
สตริงคือคอลเลกชันของตัวอักษร ในภาษา Go, สตริงเป็นที่ไม่สามารถเปลี่ยนแปลงได้ แต่ละสตริงประกอบด้วยสองส่วน: ตัวชี้ไปที่อาร์เรย์ไบต์ระยะหนึ่ง และความยาว สตริงสามารถบรรจุข้อมูลใด ๆ รวมถึงไบต์
5.2 การใช้งานตัวแปรสตริง
ตัวแปรสตริงสามารถประกาศโดยใช้เครื่องหมายคำพูดดับเบิล "
เพื่อสร้าง แต่คุณยังสามารถใช้เครื่องหมาย backticks ` เพื่อสร้างสตริงหลายบรรทัด:
package main
import "fmt"
func main() {
var s1 string = "hello"
s2 := "world"
s3 := `This is a
multiple line
string`
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
}
เมื่อสตริงถูกสร้างแล้ว สิ่งที่อยู่ภายในสตริงไม่สามารถเปลี่ยนแปลงได้ การดำเนินการต่อไปนี้ไม่ถูกต้องและจะทำให้เกิดข้อผิดพลาดในการคอมไพล์:
s := "hello"
s[] = 'H` // ข้อผิดพลาดในการคอมไพล์: เนื้อหาของสตริงไม่สามารถเปลี่ยนแปลงได้
5.3 การดำเนินการกับสตริง
สตริงเป็นสิ่งที่พบมากและสำคัญในการเขียนโปรแกรม ภาษา Go มีคำสั่งภายในที่มีคุณสมบัติมากมายสำหรับการจัดการกับสตริง นี่คือแนวทางในการใช้งานบางอย่างที่นิยม
5.3.1 การต่อสตริง
ในภาษา Go, คุณสามารถใช้ตัวดำเนินการบวก (+
) เพื่อต่อสตริง ซึ่งเป็นวิธีที่เข้าใจง่ายที่สุด นอกจากนี้เมื่อจัดการกับการต่อสตริงหลายๆ สตริงบ่อยครั้ง แนะนำให้ใช้ strings.Builder
เพื่อประสิทธิภาพที่ดีขึ้น
package main
import (
"fmt"
"strings"
)
func main() {
// การต่อสตริงโดยใช้ +
hello := "Hello, "
world := "World!"
result := hello + world
fmt.Println(result) // ผลลัพธ์: Hello, World!
// การต่อสตริงโดยใช้ strings.Builder
var sb strings.Builder
sb.WriteString("Hello, ")
sb.WriteString("World!")
fmt.Println(sb.String()) // ผลลัพธ์: Hello, World!
}
5.3.2 การแบ่งสตริง
การแบ่งสตริงสามารถทำได้โดยใช้ฟังก์ชัน strings.Split
ซึ่งจะทำการแบ่งสตริงเป็นส่วนย่อย ๆ โดยใช้ตัวคั่นที่กำหนดไว้
package main
import (
"fmt"
"strings"
)
func main() {
// กำหนดค่าสตริง
sentence := "Go คือ ภาษาโปรแกรมชิ้นโค้กแห่งเปิด"
// แบ่งสตริงด้วยช่องว่าง
words := strings.Split(sentence, " ")
for _, word := range words {
fmt.Printf("%s\n", word)
}
// ผลลัพธ์:
// Go
// คือ
// ภาษาโปรแกรมชิ้นโค้กแห่งเปิด
}
5.3.3 การเข้าถึงดัชนี
ใน Go, สตริงคือลำดับของไบต์ที่ไม่เปลี่ยนแปลง คุณสามารถใช้การเข้าถึงดัชนีเพื่อเข้าถึงไบต์ที่แน่นอนในสตริง อย่างไรก็ตาม สำคัญที่ต้องระบุว่าเนื่องจากสตริงอาจมีตัวอักษรหลายไบต์ (เช่น ตัวอักษรที่เข้ารหัสด้วย UTF-8) การเข้าถึงดัชนีโดยตรงอาจไม่ให้ผลลัพธ์ตามที่คาดหวัง
package main
import "fmt"
func main() {
s := "สวัสดี, โลก"
for i := ; i < len(s); i++ {
fmt.Printf("%d: %x\n", i, s[i])
}
// หมายเหตุ: นี้จะแสดงผลลัพธ์เป็นการแสดงเลขฐานสิบหกของไบต์ ไม่ใช่ตัวอักษร
}
เพื่อหาอักษรตามลำดับในสตริง คุณสามารถใช้ลูป range
package main
import "fmt"
func main() {
s := "สวัสดี, โลก"
for index, runeValue := range s {
fmt.Printf("%d: %U '%c'\n", index, runeValue, runeValue)
}
// ผลลัพธ์: ดัชนี, การเข้ารหัส Unicode, และตัวอักษรเองสำหรับแต่ละตัวอักษร
}
5.3.4 การรับความยาว
ฟังก์ชัน len
สามารถหาความยาวของสตริงได้ กล่าวคือ ความยาวของลำดับไบต์ที่เป็นพื้นฐาน สำหรับสตริงที่ใช้เข้ารหัสด้วย UTF-8 หากคุณต้องการหาจำนวนตัวอักษร (runes) คุณควรใช้ฟังก์ชัน utf8.RuneCountInString
ซึ่งสามารถจัดการตัวอักษรหลายไบต์ได้อย่างถูกต้อง
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "สวัสดี, โลก"
fmt.Println("ความยาวของไบต์:", len(s)) // แสดงความยาวของไบต์
fmt.Println("ความยาวของตัวอักษร:", utf8.RuneCountInString(s)) // แสดงความยาวของตัวอักษร
}
จากตัวอย่างข้างต้น เราสามารถเห็นได้ว่า ภาษา Go มีฟังก์ชันต่าง ๆ ที่มีความสามารถในการดำเนินการกับสตริงอย่างหลากหลาย ทำให้ง่ายต่อการทำงานกับสตริงต่าง ๆ เมื่อเขียนโปรแกรมสำคัญที่ต้องใส่ใจถึงความแตกต่างระหว่างไบต์ และ ตัวอักษรโดยเฉพาะอย่างยิ่งเมื่อจัดการกับเซตตัวอักษรที่ไม่ใช่ ASCII