Go Map ve Struct
Bu yazıda Go programlama dilindeki map ve struct tiplerinden bahsedeceğim
Map
Map key/value yapısıyla ilişkilendirilen unordered bir veri yapısıdır. Map içindeki keyler birbiriyle aynı tipte, valuelar da birbiriyle aynı tipte olmak zorundadır. Key ve value birbirinden farklı tipte olabilir. Key değerleri comparable olmalıdır. Mapin zero valuesu nil dir.
Built-in fonksiyon olan make ile map oluşturabilriz.
drivers :=make(map[string]string])
Ayrıca map anahtar kelimesi ile de başlangıç değerleri ile bir map oluşturabiliriz
drivers := map[string]string{
"Hamilton" : "Mercedes-AMG Patronas",
"Vettel": "Scuderia Ferrari",
}
drivers :=make(map[string]string])
drivers["Hamilton"] = "Mercedes-AMG Patronas"
drivers["Vettel"] = "Scudria Ferrari"
Yukarıdaki iki kullanım birbirinin eşdeğeridir.
Map içindeki bir veriye aşağıdaki gibi ulaşılabilir
fmt.Println(drivers["Hamilton"]) // Mercedes-AMG Patronas
Map içinden bir veriyi silmek için built-in delete fonksiyonu kullanılır
delete(drivers, "Vettel") // drivers["Vettel"] değerini siler
Yukarıda bahsettiğimiz map içinden bir veriye erişme ve bir veriyi silme operasyonları, ilgili değer map içinde olmasa dahi güvenli işlemlerdir çünkü map lookup işlemi eğer ilgili key değeri map içinde mevcut değilse, o tipin zero value değerini döner.
points := map[string]int{
"Hamilton" : 347,
"Bottas": 223,
"Verstappen": 214,
}
fmt.Println(points["Vettel"]) //0
Yukarıdaki örnekte Vettel map içinde olmadığı için ekrana int değerinin zero value su olan 0 yazar
Her ne kadar yukarıdaki işlemler zero value değeri dönse de bazı durumlarda ilgili key in map içinde olup olmadığından emin olmak isteriz.
name, ok := drivers["Sainz"]
if !ok {
//Sainz map içinde yok, name değeri " "
}
Yukarıdaki drivers[“Sainz”] işlemi 2 değer geri döndürür. ilk değer map içindeki ilgili key in değeri, ikinci değer ise boolean tipinde ilgili elemanın map içinde olup olmadığı bilgisidir.
Map unordered list olduğu için her map üzerindeki iteration her zaman aynı sıralama ile olmaz. Eğer map içindeki değerleri sıralı bir şekilde almak istiyorsak, map içindeki key leri ayrıca sıralamak gerekiyor.
drivers := map[string]string{
"Hamilton": "Mercedes-AMG Patronas",
"Verstappen": "Aston Martin Redbull",
"Vettel": "Scuderia Ferrari",
"Norris": "McLaren",
}
var names = make([]string, 0, len(drivers))
for name := range drivers {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
fmt.Printf("%s\t%s\n", name, drivers[name])
}
//Hamilton Mercedes-AMG Patronas
//Norris McLaren
//Verstappen Aston Martin Redbull
//Vettel Scuderia Ferrari
Struct
Struct sıfır veya daha fazla veri türünü tek bir yapı altında gruplayan bir veri türüdür. Struct içindeki her bir değer field olarak adlandırılır. Struct Go’da özel karmaşık türler oluşturmak için kullanılır. Struct tipinin zero value su her bir elemanının zero value sudur
Struct Tanımlama
type Student struct {
ID int
Name string
Address string
}
Struct Kullanımı
var furkan Student
s := Student{}
Struct ı başlatırken elemanlarına değer verip de başlatabilirz
s := Student{
Name: "Furkan Beğen",
Email: "mail@example.com",
}
Bunu yaparken bütün elamanlara değer vermek zorunda değiliz. İstediğimiz kadar elemana değer vererek sturct ı başlatabiliriz
s := Student{
Email: "s@example.com",
}
Bir struct ın elemanlarına(field) larına nokta(.) notasyonu ile erişebiliriz
furkan.Name = "Furkan"
Bir struct a aynı struct tipinde bir eleman deklare edemeyiz. Aşağıdaki kod compile olmaz
type Employee struct {
Name string
Email string
Salary int
Employee Employee
}
Fakat bir struct a aynı struct tipinde elemanı pointer tipinde deklare edebiliriz
type Employee struct {
Name string
Email string
Salary int
Employee *Employee
}
Struct değerleri fonksiyonlara argüman olarak geçilebilir ve fonksiyonların dönüş değeri olabilir
func giveRaise(e Employee, percent int) int {
return e.Salary * percent / 100
}
Verimlilik açısından büyük struct tipleri fonksiyonlara parametre olarak geçilecekse veya fonksiyonların dönüş değeri olacaksa pointer kullanılır. Ayrıca pointer kullanımı eğer fonksiyon argümanının değerinde bir değişiklik yapacaksa zorunludur. Çünkü Go dili call-by-value bir dildir ve fonksiyon argümanın kendisini değil bir kopyasını alır.
func giveRaise(e *Employee, percent int) int {
return e.Salary * percent / 100
}
Struct ın bütün alanları karşılaştırılabilir(comparable) ise struc ın kendisi de karşılaştırılabilirdir. Böylelikle == ve ≠ gibi operatörleri kullanabiliriz. == operatörü iki struct ın karşılıklı alanlarını sırasıyla karşılaştırır.
func main() {
type Coordinate struct {
X int
Y int
Z int
}
c1 := Coordinate{X: 0, Y: 0, Z: 0}
c2 := Coordinate{X: 1, Y: 0, Z: 0}
if c1 == c2 {
fmt.Println("Koordinatlar eşit")
} else {
fmt.Println("Koordinatlar eşit değil")
}
}