Go ด้วยกัน Go ได้ไกล-array, slice, make(), range, map [EP.4]
ยังอยู่ในเรื่อง Control flow นะคับ มาต่อกันเลย
- Array
- Slice
- Make function
- Range
- Map
1. Array
- Array ก็เหมือนกับ List ใน Python แต่ในการสร้างจะมี pattern ต่างกันนิดนึงคือ
var array_variable = [size]data_type{elements of array}
- ไม่งงใช่ไหม สร้าง array จะขึ้นต้นด้วย
var + <array name>
- จากนั้นก้อตามขนาดของ
array + data type + elements of array
- ถ้าไม่กำหนดขนาด array จะใช้
. . .
แทนนะ - น่าจะงงกว่าเดิม ไปดูตัวอย่างเลยดีว่าครับ
package main
import "fmt"
func main() {
// declare array variable of type integer
// defined size [size=5]
var arrayOfInteger = [5]int{1, 5, 8, 0, 3} // ประกาศให้มี int 5 ตัว
// undefined size // ถ้าไม่ระบุขนาด เราจะใช้ ... แทนนะ
var arrayOfInteger2 = [...]int{1, 5, 8, 0, 3, 4, 6, 7, 8, 9}
// using shorthand notation // หรือจะประกาศแบบย่อๆ แบบนี้ก็ได้เช่นกัน(ไม่ต้องมี var)
arrayOfInteger3 := [5]int{1, 5, 8, 0, 3}
fmt.Println(arrayOfInteger)
fmt.Println(arrayOfInteger2)
fmt.Println(arrayOfInteger3)
}
// ------------- output -------------
[1 5 8 0 3]
[1 5 8 0 3 4 6 7 8 9]
[1 5 8 0 3]
2. Slice
- ปกติแล้ว array จะมีขนาดที่ตายตัว แต่ slice จะมีขนาดที่แปรผันได้ เป็นมุมมองการเข้าถึงสมาชิกของอาเรย์แบบคล่องตัวกว่า
- ลองดูตัวอย่างคับ เป็นการเข้าถึง array เพื่อมาเป็นไว้ใน slice
- การประกาศ
[ ]
แบบนี้แบบไม่มีอะไรข้างใน เราจะเรียกว่า slice
(ไม่ใช่ array นะ)
package main
import "fmt"
func main() {
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4] // นี่เป็นการเอา primes index ที่ 1-3 ออกมานะ จึงได้ 3, 5, 7
fmt.Println(s)
}
// ------------- output -------------
[3 5 7]
- แต่เราก้อประกาศย่อๆ ได้เช่นกันนะ แบบนี้เลย
package main
import "fmt"
func main() {
names := [5]string{"love", "is", "you", "and", "me"}
fmt.Println(names)
a := names[0:2]
b := names[1:3]
fmt.Println(a, b)
b[0] = "Pawan"
fmt.Println(a, b)
fmt.Println(names)
}
- จากรูปจะพบว่า การเปลี่ยนแปลงค่าใน slice จะมีผลกับ array นะ
- slice ที่ไม่มีการเก็บค่าใดๆ เข้าไป จะมีความจุเป็น 0 และมีค่าเป็น
nil
นะ (null ใน Go นั้่นแหละ) - จิงๆ เหมือนกับ Python เลยนะ ที่ระบุได้เช่น
[0:3] ก็คือ 0, 1, 2
[:2] ก็คือ 2 ตัวแรก
[2:] ก็คือ ตั้ง index ที่ 2 ถึงท้ายสุดนั่นเอง
[:] ก็คือ เอาทุกตัว
เอาง่ายๆคือ จิงๆแล้ว slice ไม่ได้เก็บข้อมูลใดๆไว้ที่ตัวเองเลย
it’s like references to arrays
ฉะนั้นการเปลี่ยนแปลงค่า element ใน slice ก็จะส่งผลกับ element in array ด้วยเช่นกัน
3. การสร้าง slice ด้วยฟังก์ชัน make()
มี syntax คือ make()
- Creating a slice with make (เป็นการสร้าง slice ด้วยฟังก์ชั่น make และนี่คือการสร้างอาเรย์ที่มีขนาดแปรผันได้นั่นเอง)
- Function
make
นี้จะสร้าง array ที่มีความยาวเท่ากับศูนย์และ return slice ที่อ้างไปถึงอาเรย์ตัวนั้นออกมา
จำง่ายๆ
make()
คือการสร้าง array นั่นแหละ ที่ง่ายขึ้น
package main
import "fmt"
func main() {
// Create a slice with make(), specifying length 3
a := make([]int, 3) // ถ้าระบุแค่นี้จะได้ len=3, cap=3 คือได้ [0,0,0] นั่นเอง
// Print length and capacity
fmt.Println("Slice with make([]int, 3)")
fmt.Println("Length:", len(a)) // Output: 3
fmt.Println("Capacity:", cap(a)) // Output: 3
}
- ลองดูอีกตัวอย่างโดยเป็นการระบุ 3 arguments นะคับ
package main
import "fmt"
func main() {
// Create a slice with make(), specifying length 3 and capacity 5
b := make([]int, 3, 5)
// Print initial length and capacity
fmt.Println("Initial slice")
fmt.Println("Length:", len(b)) // Output: 3
fmt.Println("Capacity:", cap(b)) // Output: 5
// Append an element to the slice
b = append(b, 4)
fmt.Println("\nAfter appending one element")
fmt.Println("Length:", len(b)) // Output: 4
fmt.Println("Capacity:", cap(b)) // Output: 5
// Append another element to the slice
b = append(b, 5)
fmt.Println("\nAfter appending another element")
fmt.Println("Length:", len(b)) // Output: 5
fmt.Println("Capacity:", cap(b)) // Output: 5
// Append more elements to exceed the initial capacity
b = append(b, 6)
fmt.Println("\nAfter appending enough elements to exceed the initial capacity")
fmt.Println("Length:", len(b)) // Output: 6
fmt.Println("Capacity:", cap(b)) // Output: 10
}
4. range()
คล้ายๆกับ Python เลยนะคือ มี range ด้วย แต่สำหรับ Go มักจะใช้ร่วมกับ for-loop เช่นกันและ return 2 values คือ index and value
รูปแบบการใช้นะ
for i, _ := range <arrays>
กรณีต้องการแค่ indexfor _, value := range <arrays>
กรณีต้องการแค่ valuefor i := range <arrays>
กรณีต้องการแค่ index
package main
import "fmt"
func main() {
numbers := []int{10, 20, 30, 40, 50}
for index, value := range numbers {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
}
// =============== output =================
Index: 0, Value: 10
Index: 1, Value: 20
Index: 2, Value: 30
Index: 3, Value: 40
Index: 4, Value: 50
ถ้าไม่ได้ใช้ array ก็ใช้ range ได้เช่นกันนนะ เช่น string แบบเคสนี้
package main
import "fmt"
func main() {
greeting := "Hello, 世界"
for index, runeValue := range greeting {
fmt.Printf("Index: %d, Rune: %c\n", index, runeValue)
}
}
// =============== output =================
Index: 0, Rune: H
Index: 1, Rune: e
Index: 2, Rune: l
Index: 3, Rune: l
Index: 4, Rune: o
Index: 5, Rune: ,
Index: 6, Rune:
Index: 7, Rune: 世
Index: 10, Rune: 界
5. Map
Map จะเหมือนกับ dict ใน Python, หรือ map ใน Dart เลยนะ คือ เป็น{key: value}
ซึ่งใน Go จะมี pattern แบบนี้
package main
import "fmt"
func main() {
// สร้าง map
m := make(map[string]int)
// เพิ่มค่าใน map
m["one"] = 1
m["two"] = 2
m["three"] = 3
// เข้าถึงและแสดงค่าจาก map
fmt.Println("Value for key 'one':", m["one"])
// ตรวจสอบว่ามีคีย์อยู่ใน map หรือไม่
if value, ok := m["two"]; ok {
fmt.Println("Value for key 'two':", value)
} else {
fmt.Println("Key 'two' does not exist")
}
// ลบค่าออกจาก map
delete(m, "two")
// ตรวจสอบหลังจากลบค่า
if _, ok := m["two"]; !ok {
fmt.Println("Key 'two' has been deleted")
}
}
- เพื่อให้เข้าใจได้ง่าย นี่คือการตรวจสอบว่ามีคีย์ใน map หรือไม่
// เราจะใช้ ok ซึ่งเป็นค่าที่ได้คืนมาในการตรวจสอบว่ามี "three" ใน map ที่ชื่อ m หรือไม่
// ถ้ามีก็จะได้ value ของ m["three"] ออกมานะ และ ok จะได้เป็น True
value, ok := m["three"]
if ok {
fmt.Println("Key exists:", value)
} else {
fmt.Println("Key does not exist")
}
If you think it’s useful for you, just clap your hands 👏 to be encouraged me.
แล้วพบกันใหม่ตอนถัดไปคับ