Slice үйлдлүүд
Өмнөх хичээлд slice үүсгэж, append ашиглаж сурсан. Энэ хичээлд slice-тай ажиллах илүү дэвшилтэт үйлдлүүдийг судална — элемент устгах, slice хуулах, болон capacity гэх ойлголтыг тайлбарлана.
Эдгээр үйлдлүүдийг мэдсэнээр бодит программ бичихэд тохиолдох ихэнх нөхцлийг шийдэж чадна.
Slice хуулах — copy
copy функц нь нэг slice-н утгуудыг нөгөөд хуулна. Энэ нь чухал — учир нь slice хуулахгүй бол хоёр хувьсагч нэг санах ойг заах тул нэгийг нь өөрчлөхөд нөгөө нь ч өөрчлөгдөнө.
package main
import "fmt"
func main() {
эх := []int{1, 2, 3, 4, 5}
// Шинэ slice үүсгэж хуулна
хуулбар := make([]int, len(эх))
copy(хуулбар, эх)
// Хуулбарыг өөрчилсөн ч эх өөрчлөгдөхгүй
хуулбар[0] = 99
fmt.Println("Эх:", эх) // [1 2 3 4 5]
fmt.Println("Хуулбар:", хуулбар) // [99 2 3 4 5]
}
Дэлгэцэнд:
Эх: [1 2 3 4 5]
Хуулбар: [99 2 3 4 5]
copy(хуулбар, эх) нь "эх slice-н утгуудыг хуулбар slice-д хуул" гэсэн үг. Хуулсны дараа тэд бие даасан slice болно.
Элемент устгах
Go-д slice-с элемент устгах суурилагдсан функц байхгүй. Харин append болон хэсэглэлтийг хослуулан ашиглана:
package main
import "fmt"
func main() {
өнгөнүүд := []string{"улаан", "ногоон", "цэнхэр", "шар", "цагаан"}
// 2 дугаар index (цэнхэр) устгах
устгах := 2
өнгөнүүд = append(өнгөнүүд[:устгах], өнгөнүүд[устгах+1:]...)
fmt.Println(өнгөнүүд) // [улаан ногоон шар цагаан]
fmt.Println("Урт:", len(өнгөнүүд)) // 4
}
Дэлгэцэнд:
[улаан ногоон шар цагаан]
Урт: 4
өнгөнүүд[:2] нь "цэнхэр"-ийн өмнөх хэсэг, өнгөнүүд[3:] нь "цэнхэр"-ийн дараах хэсэг. append тэдгээрийг нэгтгэнэ. Ингэснээр "цэнхэр" алга болно.
len ба cap — урт ба хүчин чадал
Slice-д хоёр чухал шинж чанар байдаг: len (одоогийн элементийн тоо) ба cap (нийт хүчин чадал):
package main
import "fmt"
func main() {
// make([]int, урт, хүчин_чадал)
с := make([]int, 3, 10)
fmt.Println("Урт:", len(с)) // 3
fmt.Println("Хүчин чадал:", cap(с)) // 10
с = append(с, 42)
fmt.Println("append дараа урт:", len(с)) // 4
fmt.Println("append дараа хүчин чадал:", cap(с)) // 10 — өөрчлөгдөөгүй
}
Дэлгэцэнд:
Урт: 3
Хүчин чадал: 10
append дараа урт: 4
append дараа хүчин чадал: 10
cap нь slice-д хэдэн элемент багтах боломжтой болохыг заана. Хэрэв append хийхэд хүчин чадал хүрэлцэхгүй бол Go нь автоматаар хоёр дахин том санах ой гарган шилжүүлнэ. Урьдчилан cap тогтоох нь үүнийг сэргийлж гүйцэтгэлийг сайжруулдаг.
Slice-г функцт дамжуулах
Slice-г функцт дамжуулахад pointer шиг ажилладаг — функц дотор өөрчилсөн утга эх slice-д нөлөөлнө:
package main
import "fmt"
func хоёрдахин(тоонууд []int) {
for i := range тоонууд {
тоонууд[i] *= 2
}
}
func main() {
утгууд := []int{1, 2, 3, 4, 5}
fmt.Println("Өмнө:", утгууд)
хоёрдахин(утгууд)
fmt.Println("Дараа:", утгууд)
}
Дэлгэцэнд:
Өмнө: [1 2 3 4 5]
Дараа: [2 4 6 8 10]
Slice нь дотроо массивын pointer агуулдаг тул функцт дамжуулахад хуулбар үүсэхгүй, шууд ажилладаг. Энэ нь гүйцэтгэлийн хувьд сайн шинж юм.
Дараагийн хичээлд:
Map буюу түлхүүр-утга хосын өгөгдлийн бүтцийг судална. Map нь "Нэр → Утас дугаар" гэх мэт хос мэдээллийг хадгалахад хамгийн тохиромжтой бүтэц юм.