18 Aralık 2024 Çarşamba

Go Programlama Dili - 2

 Selam Go dilini öğrenmeye kaldığım yerden devam ediyorum. Nerede kalmıştık?


Go Operatörleri

Operatörler değişkenlerle ve değerlerle işlemler yapmanızı sağlar. 

Örneğin + operatörü aşağıda örnekte görüldüğü gibi toplamanızı sağlar.

package main
import "fmt"

func main() {
  var a = 15 + 25
  fmt.Println(a)
}

Bu + operatörü iki değeri toplamakta kullanıldığı gibi iki değişkenin sakladığı değerleri toplamakta veya bir değer ile bir değişkeni toplamakta da kullanılabilir.

package main

import "fmt"

func main() {
    var (
        toplam1 = 100 + 50          // 150 (100 + 50)
        toplam2 = toplam1 + 250     // 400 (150 + 250)
        toplam3 = toplam2 + toplam2 // 800 (400 + 400)
    )
    fmt.Println(toplam3)
}


Go operatörleri aşağıdaki gruplara ayrılır.

  • Aritmetik İşlemler
  • Atama İşlemleri
  • Karşılaştırma İşlemleri
  • Lojik İşlemleri
  • Bit Seviyesi İşlemler


Go Aritmetik Operatörler

Temel matematik işlemlerini gerçekleştirmek için kullanılan operatörlerdir.

OperatörİsimAçıklamaÖrnek
 +Toplamaİki değeri toplarx + y
 -ÇıkartmaBir değeri diğerinden çıkartırx - y
 *Çarpmaİki değeri çarparx * y
 /BölmeBir değeri diğerine bölerx / y
 %Mod hesabıBölümden kalan değeri bulurx % y
 ++ArttırmaDeğişken değerini 1 arttırırx++
 --EksiltmeDeğişken değerini 1 azaltırx--


Go Atama Operatörleri

Atama operatörleri değişkenlere değer girmek (atamak) için kullanılır. 

Aşağıdaki örnekte atama operatörü (=) ile x değişkenine 10 değeri giriliyor :

package main

import "fmt"

func main() {
    var x = 10
    fmt.Println(x)
}

Toplayıp atama operatörü ( += )  ile değişken değerine başka bir değer toplanır. 

package main

import "fmt"

func main() {
    var x = 10
    x += 5
    fmt.Println(x)
}

x += 5 aslında x = x + 5 ile aynı işi yapan kısaltılmış bir deyim şeklidir. 

Atama operatörlerinin bir listesi şöyle:

OperatörÖrnekŞununla Aynı
 =x = 5x = 5
 +=x += 3x = x + 3
 -=x -= 3x = x - 3
 *=x *= 3x = x * 3
 /=x /= 3x = x / 3
 %=x %= 3x = x % 3
 &=x &= 3x = x & 3
 |=x |= 3x = x | 3
 ^=x ^= 3x = x ^ 3
 >>=x >>= 3x = x >> 3
 <<=x <<= 3x = x << 3


Go Karşılaştırma Operatörleri

Karşılaştırma operatörleri iki değeri karşılaştırırken kullanılır. 

Not : Karşılaştırmaların sonuçları her zaman ya true (1) ya da false (0) olur.

Örnekte 5 değerinin 3 değerinden büyük olmasını > karşılaştırması ile test ediyoruz.

package main

import "fmt"

func main() {
    var x = 5
    var y = 3
    fmt.Println(x > y) // 1 (true) çünkü 5, 3'ten büyük
}

Tüm karşılaştırma operatörlerinin bir listesi.

OperatörİsimÖrnek
 ==Eşit mi?x == y
 !=Eşit değil mi?x != y
 >Büyük mü?x > y
 <Küçük mü?x < y
 >=Büyük veya eşit mi?x >= y
 <=Küçük veya eşit mi?x <= y


Go Lojik Operatörleri

Lojik operatörler birkaç karşılaştırmanın sonuçlarını birlikte değerlendirirken kullanılır. 

OperatörİsimAçıklamaÖrnek
 &&Lojik ve işlemiHer iki değerde true ise true olurx < 5 &&  x < 10
 ||Lojik vaya işlemiİki değerden biri bile true ise true olurx < 5 || x < 4
 !Lojik değil işlemiDeğerin tersini alır , true ise false, false ise true olur!(x < 5 && x < 10)


Go Bit Seviyesi Operatörler

Değerleri binary (ikili sistem) olarak ele alarak bit bit işlem yaparlar.

OperatörİsimAçıklamaÖrnek
 &ANDHer iki taraftaki bit de 1 ise o biti setlerx & y
 |ORHerhangi bir taraftaki bit 1 ise o biti setlerx | y
 ^XORSadece bir taraftaki bit 1 ise o biti setlerx ^ b
 <<Sola kaydırBitleri sola kaydırır, sağdan sıfır girerx << 2
 >>Sağa kaydırBitleri sağa kaydırır, soldan sıfır girerx >> 2



Go Dilinde Koşullar

Koşullu yapılar belirli şartlara göre işlemler yapmak için kullanılır.

Bir koşulun değeri true ya da false olabilir.

Go dili standart matematik karşılaştırmalarını koşullarda kullanır. 

  • < - küçüktür
  • <= - küçük veya eşittir
  • > - büyüktür
  • >= - büyük veya eşittir
  • == - eşittir karşılaştırması
  • != - eşit değildir karşılaştırması

Bunlara ek olarak değerleri birlikte işleyen lojik operatörler de kullanılır.

  • && - lojik AND
  • || - lojik OR
  • ! - lojik NOT

Bu operatörler yardımıyla birçok karşılaştırma sonucu amaca göre birleştirilir. Örneğin:

  • x > y
  • x != y
  • (x > y) && (y > z)
  • (x == y) || z

Go dilinde aşağıdaki koşullu işlem yapıları kullanılır:

  • Sadece bir koşulun geçerli olduğunda çalışacak kodlar için if deyimi
  • if deyimindeki koşul geçersiz olursa çalışacak kodlar için else deyimi
  • İlk koşul geçersiz olunca başka bir koşul ile çalışacak kodlar için else if deyimi
  • Birçok alternatif koşula göre çalışacak kodları içeren switch yapısı


Go if Yapısı

if yapısı eğer koşuldan true değeri çıkarsa işletilecek olan kodları bir blok içine toplayan yapıdır.

Deyim yapısı :

    if koşul {
        // eğer koşul true ise işlenecek kodlar
    }

Not : if deyimi küçük harfle yazılır If ya da IF gibi yazımlar hata verir.

Aşağıdaki örnekte 20'nin 18'den büyük olmasını test ediyoruz, koşul true sonuç verince terminale bir çıktı yazılır.

package main

import "fmt"

func main() {
    if 20 > 18 {
        fmt.Println("20 değeri 18'den büyük")
    }
}

Koşullarda değişkenleri de kullanabiliriz tabii ki.

package main

import "fmt"

func main() {
    x := 20
    y := 18
    if x > y {
        fmt.Println("x y'den büyük")
    }
}

Bu örnekte x ve y adı verilen iki değişken kullandık ve x'in y'den büyük olmasını test ettik ( > operatörünü kullanarak). x değeri 20 ve y değeri 18 olduğu için x y'den büyüktür.


Go if else Yapısı

else deyimi if deyimi ile birlikte kullanılır ve eğer if ile verilen koşul false değer verirse (yani yanlışsa) çalışacak kodların bloğunu belirler. 

Deyim yapısı :

    if condition {
        // koşul true ise çalışacak kodlar
    } else {
        // koşul false ise çalışacak kodlar
    }


if else Yapısı Kullanımı

Aşağıdaki örnekte zaman (20) değeri 18'den büyük. Bu durumda if koşulu false sonuç verir. Bu sebeple if bloğundaki kodlar işlenmeyip sonrasında gelen else bloğuna geçilir ve ekrana "İyi Akşamlar" yazılır. Eğer zaman değerine 18'den küçük bir değer verilirse bu sefer ekrana "İyi Günler" yazacaktır.

package main

import "fmt"

func main() {
    zaman := 20
    if zaman < 18 {
        fmt.Println("İyi Günler")
    } else {
        fmt.Println("İyi Akşamlar")
    }
}


Bu örnekte sıcaklık değeri 14, bu durumda if koşulu false sonuç verir ve else bloğundaki kodlar çalışır.

package main

import "fmt"

func main() {
    sıcaklık := 14
    if sıcaklık > 15 {
        fmt.Println("Dışarısı sıcak")
    } else {
        fmt.Println("Dışarısı soğuk")
    }
}

Önemli konu, else yapısındaki süslü parantezlerin yazımı } else { şeklinde olmalıdır.

Örneğin else deyimini başka satıra yazmak hata verir.

    if sıcaklık > 15 {
        fmt.Println("Dışarısı sıcak")
    }
    else {
        fmt.Println("Dışarısı soğuk")
    }

ve sonuç :

./conds.go:10:2: syntax error: unexpected else, expected }



Go else if Yapısı

Eğer önceki koşul false verdiğinde yeni bir koşul test etmek istiyorsak else if bloğunu kullanırız. 

Deyim yapısı :

if koşul_1 {
    // koşul_1 doğruysa işlenecek
 } else if koşul_2 {
    // koşul_1 yanlış ve koşul_2 doğruysa işlenecek
 } else {
    // her iki koşul da yanlışsa işlenecek
 }


Bu örnekte bir else if kullanımı görülüyor.

package main

import "fmt"

func main() {
    saat := 22
    if saat < 10 {
        fmt.Println("Günaydın")
    } else if saat < 20 {
        fmt.Println("İyi Günler")
    } else {
        fmt.Println("İyi Akşamlar")
    }
}

sonuç :

İyi Akşamlar

Örnekte saat değeri (22) , 10'dan büyük , yani ilk koşul false sonuç verir. Sonraki koşul else if satırında ve o da false sonuç veriyor. Program akışı en sondaki else bloğundaki kodları işleyecektir ve "İyi Akşamlar" çıktısı verecektir.

Ama saat değeri 14 olsa programımız "İyi Günler" çıktısı verecektir.

Diğer bir else if kullanım örneği :

package main

import "fmt"

func main() {
    a := 14
    b := 14
    if a < b {
        fmt.Println("a değeri b'den küçük")
    } else if a > b {
        fmt.Println("a değeri b'den büyük")
    } else {
        fmt.Println("a ve b değerleri eşit")
    }
}

sonuç : 

a ve b değerleri eşit


Eğer koşul_1 ve koşul_2 her ikisi de doğruysa sadece koşul_1 bloğu işlenir program koşul_2'ye bakmadan atlar.

Örnek :

package main

import "fmt"

func main() {
    x := 30
    if x >= 10 {
        fmt.Println("x değeri 10 veya daha büyük")
    } else if x > 20 {
        fmt.Println("x değeri 20'den büyük")
    } else {
        fmt.Println("x değeri 10'dan küçük")
    }
}

sonuç : 

x değeri 10 veya daha büyük

Gördüğünüz gibi ikinci koşul doğru olmasına rağmen program kaale almadan geçti. Bu şekil if - else if - else if - ... - else yapılarında akışın önüne ilk çıkan doğru koşul işlenir ve bloklar komple atlanır.

Bu arada, else if bloklarını birbiri arkasına istediğiniz kadar ekleyebilirsiniz. En başta if bloğu olmasına ve eğer gerekiyorsa else bloğunun en sonda olmasına dikkat edin. 


Go İç içe (Nested) if Yapıları

Eğer ihtiyaç duyarsak bir if bloğunun içinde başka bir if bloğu da kullanabiliriz (sonuçta bir kod bloğu). Buna iç içe if (nested if) kullanımı denir.

Deyim yapısı :

    if koşul_1 {
        // koşul_1 doğruysa çalışacak kodlar
        if koşul_2 {
            // hem koşul_1 hem de koşul_2 doğruysa
            // işlenecek kodlar
        }
    }

Bu arada , gösterim böyle ama koşul_1 doğruysa işlenecek kodlar koşul_2 bloğundan sonra da yazılabilir. İhtiyaca göre değişir.

    if koşul_1 {
        // koşul_1 doğruysa çalışacak kodlar
        if koşul_2 {
            // hem koşul_1 hem de koşul_2 doğruysa
            // işlenecek kodlar
        }
// koşul_1 doğruysa çalışacak kodlar
    }

gibi.

Örnekte iç içe if blokları kullanımı görülüyor.

package main

import "fmt"

func main() {
    num := 20
    if num >= 10 {
        fmt.Println("Num değeri 10 veya daha büyük")
        if num > 15 {
            fmt.Println("Num değeri 15'ten de büyük")
        }
    } else {
        fmt.Println("Num değeri 10'dan küçük")
    }
}

sonuç :

Num değeri 10 veya daha büyük
Num değeri 15'ten de büyük


Go switch Yapısı

switch yapısını birçok kod bloğundan bir tanesini çalıştırmak için kullanırız.

Go'da switch yapısı C, C++, Java, JavaScript, ve PHP gibi dillere benzer. Aradaki fark, Go'da sadece ilk eşleşen koşulun bloğu işlenir gerisi atlanır ve bu yüzden break benzeri komutlara gerek kalmaz. 

Tek Durumlu switch Yapısı

Deyim yapısı şöyle :

    switch işlem {
    case x:
       // kod bloğu
    case y:
       // kod bloğu
    case z:
    ...
    default:
       // kod bloğu
    }  

Önce işlem ile verilen şey yapılır ve sonucu bulunur. Sonuç x değerine eşitse case x: bloğu , y değerine eşitse case y: bloğu , z değerine eşitse case z: bloğu ve hiç birine eşit değilse default: bloğu çalıştırılır.

default bloğunu koymak zorunda değiliz, sadece hiç bir değer eşleşmezse çalışmasını istediğimiz kodlar varsa kullanırız.

Örnek.

package main

import "fmt"

func main() {
    gün := 4

    switch gün {
    case 1:
        fmt.Println("Pazartesi")
    case 2:
        fmt.Println("Salı")
    case 3:
        fmt.Println("Çarşamba")
    case 4:
        fmt.Println("Perşembe")
    case 5:
        fmt.Println("Cuma")
    case 6:
        fmt.Println("Cumartesi")
    case 7:
        fmt.Println("Pazar")
    }
}

sonuç :

Perşembe


default bloğu kullanımına bir örnek:

package main

import "fmt"

func main() {
    gün := 8

    switch gün {
    case 1:
        fmt.Println("Pazartesi")
    case 2:
        fmt.Println("Salı")
    case 3:
        fmt.Println("Çarşamba")
    case 4:
        fmt.Println("Perşembe")
    case 5:
        fmt.Println("Cuma")
    case 6:
        fmt.Println("Cumartesi")
    case 7:
        fmt.Println("Pazar")
    default:
        fmt.Println("Hafta günü değil bu!")
    }
}

sonuç :

Hafta günü değil bu!


Tabii ki de case yanlarında verilen değerlerin hepsi aynı veri tipinde olmalıdır, yoksa hata mesajı gelir.

package main

import "fmt"

func main() {
    a := 3

    switch a {
    case 1:
        fmt.Println("a değeri bir'dir")
    case "b":
        fmt.Println("a değeri b'dir")
    }
}

sonuç :

./conds.go:11:7: cannot convert "b"
  (untyped string constant) to type int

switch satırında integer değer vermişsin , case satırında string değer veriyorsun demenin gavurcası.


Çok Durumlu switch Yapıları

Bir case bloğunda bir'den fazla değerle eşleşmeyi test etmek de mümkündür. 

    case x,y:
       // sonuç x veya y değerinde ise işlenir
    case v,w:
       // sonuç v veya w değerinde ise işlenir
    case z:
    ...
    default:
       // hiç bir durum gerçekleşmezse işlenir
    }  

Bir örnekle açıklayalım.

import "fmt"

func main() {
    gün := 5

    switch gün {
    case 1, 3, 5:
        fmt.Println("Tek iş günü")
    case 2, 4:
        fmt.Println("Çift iş günü")
    case 6, 7:
        fmt.Println("Haftasonu")
    default:
        fmt.Println("Geçersiz gün değeri")
    }
}

sonuç :

Tek iş günü



Go for Döngüleri

for döngüleri bir kod bloğunu belirlenen sayıda tekrar tekrar çalıştırmak için kullanılır.

Go dilinde sadece for döngüsü vardır (şükür, diğerlerinde bir sürü seçenek var).

Döngüler bir kod bloğunu farklı değerler kullanarak tekrar tekrar çalıştırmaya yarar. 

Her tekrarda kod bloğunun çalıştırılmasına iterasyon (yineleme) denir.

for döngüleri 3 taneye kadar ifade eki alırlar.

Deyim yapısı :

    for ifade_1; ifade_2; ifade_3 {
        // her iterasyonda çalışacak kodlar
     }


ifade_1 , sayaç değerini başlatır, for bloğunun en başında bloğa girmeden önce sadece bir kez çalıştırılır.

ifade_2 , bir koşuldur ve her yinelemenin başında işlenir ve sonuç true olursa blok işlenir yoksa for bloğu yinelemesi bitirilir çıkılır.

ifade_3 , sayaç değerini arttırır, her yineleme sonunda çalışarak sayacın bir sonraki turda kullanılacak değerini belirler.

Not : bu ifadeler aslında döngünün parametreleri değil , ama bir şekilde yazılmaları gerekiyor ve bu şekil birçok programlama dilinde kullanılan şekil.


Aşağıdaki örnek sıfırdan dörde kadar sayıları yazıyor.

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }
}

sonuç :

0
1
2
3
4

Açıklarsak:

  • i := 0 ilk ifademiz ve sadece akış bloğa ilk girerken çalışıyor, sonraki yinelemelerde çalışmıyor. Dikkat ederseniz standart değişken tanımlama satırı ve i değişkenini 0 değeri ile başlatıyor.
  • i < 5 ikinci ifade , daha önce demiştik bu bir koşul ve her yineleme başında buna bakılacak ve koşul true sonuç veriyorsa yineleme yapılacak, false verince yineleme yapılmadan döngü bitirilecek. Bu yüzden değer 5 olunca onu ekrana yazmadan bitiriyor.
  • i++ üçüncü ifade yani her turun sonunda çalışan ifade, buraya gelmeden önce blok içindeki kod bir kere işleniyor. Burada da sayaç değeri 1 arttırılıyor (mesela i += 2 yazıp ikişer de arttırabilirdik). 

Döngü ikinci ifadedeki koşul false verene kadar devam eder. Mesela oraya i < 5 yerine true yazsak döngü sonsuza kadar devam eder. Ya da üçüncü ifadede i++ yerine i = 0 yazsak sayaç hep sıfır olacağı için koşul her zaman true sonuç verir ve döngü sonsuza kadar devam eder. İşte bilgisayarımızda bazen programların kilitlenip kalmalarının altında çoğu zaman böyle içinden çıkılamayan döngüler vardır. Yoksa milyon satır kod yazsanız bilgisayar onu bir-iki saniyede işler bitirir.

Aşağıdaki örnek 100'e kadar 10'ar 10'ar sayıyor.

package main

import "fmt"

func main() {
    for i := 0; i <= 100; i += 10 {
        fmt.Println(i)
    }
}

sonuç :

0
10
20
30
40
50
60
70
80
90
100


continue Deyimi

continue (devam) deyimi girildiği yerden blok sonuna atlar. Yani kod işlemesi orada bitirilip bir sonraki iterasyona geçilir. 

Örneğimiz sayacın 3 değerini pas geçiyor.

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        if i == 3 {
            continue
        }
        fmt.Println(i)
    }
}

ve sonuç :

0
1
2
4

Gördüğümüz üzere i sayacı değeri 3 olunca if bloğu aktif oluyor ve iterasyonun o satırdan sonrası işlenmeden sonrakine geçiliyor.


break Deyimi

break deyimi döngüyü iptal ederek bitirir. Bu deyimden sonraki bloktaki kodlar işlenmediği gibi sanki koşul false sonuç vermiş gibi döngü bitirilerek program döngü sonrasına atlatılır.

Örnekte sayacımız 3 değerine gelince koşul beklenmeden döngü orada bitiriliyor.

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        if i == 3 {
            break
        }
        fmt.Println(i)
    }
    fmt.Println("döngü bitti")
}

sonuç :

0
1
2
döngü bitti

Görüldüğü gibi break komutu gelir gelmez döngü orada kesilip çıkılıyor.

break ve continue deyimleri genelde if bloğunda kullanılır, koşulsuz kullanırsak her zaman çalışırlar ve blok içinde arkalarından gelen satırların bir anlamı kalmaz. Ama geçici olarak döngüde bir kısım kodu atlayıp test etme amaçlı belki kullanılabilir.


İç içe Döngüler

Aynı if bloğu gibi for döngü blokları da içi içe kullanılabilirler. Burada içte kalan döngü (inner loop) dışta kalan döngünün (outer loop) her iterasyonunda tekrar tekrar çalışır. Mesela içteki 10 dıştaki de 10 tur dönecekse içteki 10 * 10 = 100 tur dönecektir. 

Örnek :

package main

import "fmt"

func main() {
    adj := [2]string{"büyük", "leziz"}
    fruits := [3]string{"elma", "portakal", "muz"}
    for i := 0; i < len(adj); i++ {
        for j := 0; j < len(fruits); j++ {
            fmt.Println(adj[i], fruits[j])
        }
    }
}

ve çıktısı :

büyük elma
büyük portakal
büyük muz
leziz elma
leziz portakal
leziz muz


Go range Deyimi

range deyimi yardımıyla bir array, slice ya da map tipi değişkenin elemanları üzerinde iterasyon yapılabilir. Hem index hem de elemanın değerini size verir.

Kullanımı şöyledir :

    for index, değer := range array|slice|map {
        // her eleman için iterasyon yapan kodlar
    }  

Örnekte bir array üzerinde iterasyonlar yapılıyor ve hem index hem de değerler kullanılıyor (idx içinde index ve val içinde değer bulunur.

package main

import "fmt"

func main() {
    meyveler := [3]string{"elma", "portakal", "muz"}
    for idx, val := range meyveler {
        fmt.Printf("%v\t%v\n", idx, val)
    }
}

sonuç :

0       elma
1       portakal
2       muz

"\t" ile bir tab boşluğu bırakılıyor.  

Not : sadece index ya da değeri kullanmak isterseniz diğeri yerine isim olarak "_" (alt çizgi) kullanırsınız.

 Örnekte index kullanmayıp sadece değerleri kullanıyoruz.

package main

import "fmt"

func main() {
    meyveler := [3]string{"elma", "portakal", "muz"}
    for _, val := range meyveler {
        fmt.Printf("%v\n", val)
    }
}

sonuç :

elma
portakal
muz

Bu örnekte de değerleri değil indexleri kullanıyoruz.

package main

import "fmt"

func main() {
    meyveler := [3]string{"elma", "portakal", "muz"}
    for idx, _ := range meyveler {
        fmt.Printf("%d\n", idx)
    }
}

sonuç :

0
1
2




Go Fonksiyonları

Bir fonksiyon isim verilerek defalarca kullanmak üzere tanımlanmış kod bloğudur. 

Fonksiyon tanımlama bloğu içinde verilen kodlar program çalıştırılınca otomatik olarak çalışmaz.

Fonksiyon bloğunda verilen kodların çalışması için program akışı içinde o fonksiyonun çağrılması (ismi yazılarak derleyiciye burada tanımladığım fonksiyonu çalıştır denmesi) gerekir.


Go Fonksiyon Tanımlama

Bir fonksiyon tanımlamak için şunlar yapılır :

  • func kelimesi kullanılır
  • Fonksiyonun adı ve arkasından aç-kapa parantez "()" yazılır
  • Sonrasında süslü parantezler içinde fonksiyon çağrılınca çalışması istenen kod bloğu yazılır.

Deyim yapısı :

func FonksiyonAdı() {
    // çalıştırılacak kodlar
}


Go Fonksiyonun Çağrılması

Fonksiyonlar tanımlandıkları yerde çalışmazlar, sadece daha sonra çağrıldıklarında kullanılmak üzere bir kenara saklanırlar. 

Aşağıdaki örnekte "mesajım()" adında bir fonksiyon tanımlanıyor. Süslü parantezler içerisinde çalışmasını istediğimiz kodlar var. Fonksiyonu çalıştırmak için daha sonra adını arkasından parantezler gelecek şekilde yazarsınız.

package main

import "fmt"

func mesajım() {
    fmt.Println("Şimdi çalıştım!")
}

func main() {
    mesajım() // fonksiyonun çağrılması
}

sonuç :

Şimdi çalıştım!

Bir fonksiyonu defalarca çalıştırabiliriz az önceki örneği değiştirelim.

package main

import "fmt"

func mesajım() {
    fmt.Println("Şimdi çalıştım!")
}

func main() {
    mesajım()
    mesajım()
    mesajım()
}

sonuç : 

Şimdi çalıştım!
Şimdi çalıştım!
Şimdi çalıştım!


Bir de şunu belirtelim fonksiyon tanımının main bloğundan önce ya da sonra yapılmasının bir önemi yok yani şöyle de olabilir :

package main

import "fmt"

func main() {
    mesajım()
}

func mesajım() {
    fmt.Println("Şimdi çalıştım!")
}

Script dillerde genelde yazım sırasıyla program işlendiği için fonksiyonun daha önce tanımlanması gerekir, ama genelde derlenen dillerde sıralamanın önemi yoktur. 


Go Fonksiyon İsimlendirme Kuralları

  • Bir fonksiyon ismi mutlaka bir harf ile başlamalıdır
  • Bir fonksiyon adı sadece alfa-nümerik karakterler ve alt çizgi içerebilir ( A-z, 0-9, ve _ )
  • Fonksiyon isimleri büyük-küçük harf duyarlıdır
  • Fonksiyon isminde boşluk bulunamaz
  • Birden fazla kelimeden oluşan fonksiyon isimlerinde daha önce bahsettiğimiz tekniklerle kelimeler belirtilebilir

İpucu : Fonksiyonlara yaptıkları işi açıklayan isimler vermeye çalışın.


Go Fonksiyon Parametreleri

Fonksiyonların içinde kullanmak için gerekecek bilgileri parametreler ile veririz. Bu parametreler fonksiyon kodu içinde değişken gibi kullanılırlar. 

Parametreler ve veri tipleri fonksiyon tanımı yaparken isminin arkasına koyduğumuz parantezin içinde verilir. Virgüllerle ayrılmış olarak istediğiniz sayıda parametre tanımlayabilirsiniz. 

Deyim yapısı :

func FonksiyonAdı(param1 tipi, param2 tipi, param3 tipi) {
    // çalıştırılacak kod
}


Parametreli Fonksiyon Örneği

Aşağıdaki örnekteki fonksiyonun fname adında string tipi bir parametresi var. 

package main

import "fmt"

func aileAdı(fname string) {
    fmt.Println("Merhaba", fname, "Demir")
}

func main() {
    aileAdı("Hasan")
    aileAdı("İlkay")
    aileAdı("Arzu")
}

ve sonuç :

Merhaba Hasan Demir
Merhaba İlkay Demir
Merhaba Arzu Demir

Not : Bir parametre fonksiyon çağrılırken verilen değerle kullanılırken adı argüman olur. Yani fname parametre iken Hasan, İlkay ve Arzu fonksiyonda kullanılan argümanlardır. 


Birden Fazla Parametre

Bir fonksiyon tanımlarken istediğiniz sayıda parametre kullanabilirsiniz. Örnek :

package main

import "fmt"

func aileAdı(fname string, yaş int) {
    fmt.Println("Merhaba", yaş, "yaşındaki", fname, "Demir")
}

func main() {
    aileAdı("Hasan", 3)
    aileAdı("İlkay", 14)
    aileAdı("Arzu", 30)
}

Sonuç :

Merhaba 3 yaşındaki Hasan Demir
Merhaba 14 yaşındaki İlkay Demir
Merhaba 30 yaşındaki Arzu Demir

Not : Bir fonksiyonu çağırırken o fonksiyonu tanımlarken parametrelerinde belirttiğiniz sayıda argüman değeri vermelisiniz. Ayrıca değerlerin sıralamaları da fonksiyonu tanımlarken belirtildiği gibi olmalıdır.


Go Fonksiyondan Dönen Değer

Eğer fonksiyonunuzun yaptığı işlemler sonunda geriye bir değer dönmesini isterseniz, fonksiyon tanımında dönen değer veri tipini belirtirsiniz ve fonksiyon kodundan çıkarken return deyimi ile değeri belirterek bitirirsiniz. 

Deyim yapısı :

func FunctionName(param1 tipi, param2 tipi) dönen_değerin_tipi {
    // çalışacak kod
    return dönen_değer
}


fonksiyonum() adını verdiğimiz fonksiyonumuz 2 parametre alıyor ( x ve y ). Ve ikisinin toplamını ( x + y ) bir int değer olarak geri dönüyor.

package main

import "fmt"

func fonksiyonum(x int, y int) int {
    return x + y
}

func main() {
    fmt.Println(fonksiyonum(1, 2))
}

Program ekrana 3 değerini yazacaktır.


Go İsimlendirilmiş Dönen Değerler

Dönen değere bir isim vermek değişik amaçlarla gerekebilir. Mesela dönen değeri belirlediğimiz komut satırı ile fonksiyonu bitirdiğimiz return komutu ayrı yerlerde yazma ihtiyacı doğabilir. Bu durumda dönecek değere fonksiyon tanımlaması yapılırken bir isim verilerek fonksiyon içinde başka satırda değeri belirlenebilir. 

Örnekte sonuç adını verdiğimiz dönen değeri return satırından başka bir satırda belirliyoruz.

package main

import "fmt"

func fonksiyonum(x int, y int) (sonuç int) {
    sonuç = x + y
    return
}

func main() {
    fmt.Println(fonksiyonum(1, 2))
}

sonuç :

3

Yukarıdaki programın bir başka yazım şekli de şöyle olabilir:

package main

import "fmt"

func fonksiyonum(x int, y int) (sonuç int) {
    sonuç = x + y
    return sonuç
}

func main() {
    fmt.Println(fonksiyonum(1, 2))
}


Go  Fonksiyondan Dönen Değeri Bir Değişkene Saklamak

Fonksiyondan dönen değeri bir değişkene saklayıp programınız içinde değişik yerlerde kullanabilirsiniz. Aşağıda dönen değeri toplam adında bir değişkende saklayan örnek görülüyor.

package main

import "fmt"

func fonksiyonum(x int, y int) (sonuç int) {
    sonuç = x + y
    return sonuç
}

func main() {
    toplam := fonksiyonum(1, 2)
    fmt.Println(toplam)
}


Go Fonksiyonlarının Birden Fazla Değer Dönmesi

Fonksiyonun birden fazla değer dönmesini istersek dönen değerleri isimlendirmenin bir başka sebebine ulaşmış oluruz.

Örnekte fonksiyonum() metodu bir tamsayı ( sonuç ) ve bir de string ( txt1 ) değeri dönüyor.

package main

import "fmt"

func fonksiyonum(x int, y string) (sonuç int, txt1 string) {
    sonuç = x + x
    txt1 = y + " Dünya!"
    return
}

func main() {
    fmt.Println(fonksiyonum(5, "Merhaba"))
}

ve sonuç : 

10 Merhaba Dünya!


Aynı örneği dönen iki değeri iki değişkene atanır şekile çevirelim.

package main

import "fmt"

func fonksiyonum(x int, y string) (sonuç int, txt1 string) {
    sonuç = x + x
    txt1 = y + " Dünya!"
    return
}

func main() {
    a, b := fonksiyonum(5, "Merhaba")
    fmt.Println(a, b)
}


Eğer herhangi bir sebeple dönen değerlerden birini kullanmayacaksak atanacağı değişken yerine alt çizgi kullanırız ( _ ).

package main

import "fmt"

func fonksiyonum(x int, y string) (sonuç int, txt1 string) {
    sonuç = x + x
    txt1 = y + " Dünya!"
    return
}

func main() {
    _, b := fonksiyonum(5, "Merhaba")
    fmt.Println(b)
} 

sonuç :

Merhaba Dünya!


Go Kendini Çağıran Fonksiyonlar (Recursion)

Bir fonksiyonun kendini çağırmasına programcılıkta recursion denir. Fonksiyon kodu içinde kendini çağırıyorsa doğal olarak sonsuz bir döngüye girer, bunu bitirmek için tabii ki fonksiyondan çıkılacak bir koşul belirlememiz gerekir. 

Aşağıdaki örnekte sayaç() fonksiyonu kod bloğunda kendini çağırıyor. x adında bir parametremiz var ve fonksiyon çağırılınca bu değeri yazarak değerini 1 arttırıyor ve kendini tekrar çağırıyor. Bu sarmal olay x değeri 11 olduğunda bir if bloğu kullanarak bitiriliyor.

package main

import "fmt"

func sayaç(x int) int {
    if x == 11 {
        return 0
    }
    fmt.Println(x)
    return sayaç(x + 1)
}

func main() {
    sayaç(1)
}

sonuç : 

1
2
3
4
5
6
7
8
9
10

Recursion programcılıkta çok yaygın kullanılan bir konseptdir. Örneğin bir veri bloğu içinde aradığınızı bulana kadar tekrarlama yapabilirsiniz. 

Yukarıdaki örnek kısa bir örnek, lütfen kendinizi bilgisayar yerine koyup ve x'e değer vererek kodu satır satır işleyerek nasıl çalıştığını anlamaya çalışın. 

Döngüden çıkılmayacak bir değer verirseniz program sonsuz döngüye girer, mesela 

func main() {
    sayaç(12)
}

derseniz x değeri 11'den büyük ve artarak devam ediyor. 12'den itibaren tüm sayıları yazacaktır. Taa ki x değeri tüm int değerleri alıp baştan tekrar sıfıra ve 11 değerine geri dönene kadar. Kısaca görmek için değişken veri tipini int8 yapabilirsiniz.

package main

import "fmt"

func sayaç(x int8) int8 {
    if x == 11 {
        return 0
    }
    fmt.Println(x)
    return sayaç(x + 1)
}

func main() {
    sayaç(12)
}

8 bitlik sayının nasıl işlendiğinden diğerleri için bir çıkartım yapabilirsiniz.

Aşağıdaki örnekte recursif fonksiyon tanımının en çok kullanıldığı faktöriyel hesabı görülüyor. Faktöriyel demek bir sayının kendisine kadar olan tüm sayma sayılarının çarpımı demek mesela 4 faktöriyel 4 * 3 * 2 * 1 = 24 tür.

package main

import "fmt"

func faktöriyel(x float64) (y float64) {
    if x > 0 {
        y = x * faktöriyel(x-1)
    } else {
        y = 1
    }
    return
}

func main() {
    fmt.Println(faktöriyel(4))
}

sonuç :

24

Sonuçta her faktöriyel sayının bir eksiğinin faktöriyeli ile kendisini çarpımına eşit (yani 4 faktöriyel = 4 * 3 faktöriyel ----  4 * 3 * 2 * 1 => 4 * (3 * 2 * 1) gibi).

Recursion meselesi yeni karşılaşanlar için karmaşık gelebilir ve bazen yanlış kullanım sebebiyle başınızı ağrıtabilir, ancak yerinde kullanılınca işinizi çok kolaylaştıracaktır. 

Hazır faktöriyel demişken olasılık hesabı yapmadan da geçemeyeceğim. Şans Topu oyununda mesela , 1'den 34'e kadar 6 tane sayı yazıp kazanmayı bekliyoruz, peki kaç olasılık var? Buna matematikte 34'ün 6'lı kombinasyonu deniyor. Mesela a'nın b'li kombinasyonu için formül :

a! / ((a-b)! * b!)

yani 34'ün 6'lı kombinasyonu dersek

34! / ((34-6)! * 6!)

örneğe bakalım

package main

import "fmt"

func fk(x float64) (y float64) {
    if x > 0 {
        y = x * fk(x-1)
    } else {
        y = 1
    }
    return
}

func combi(a float64, b float64) float64 {
    return fk(a) / (fk(a-b) * fk(b))
}

func main() {
    fmt.Println(combi(34, 6))
}

ve sonuç :

1.344904e+06

Yani bir milyon üç yüz elli binde bir falan şansımız olur. Her seferinde 100 kolon oynasak dahi şansımız gelene kadar on binlerce kere oynamalıyız. Bunun yerine en kötü ekonomilerde bile rabbimin insanlara verdiği %10 zengin olma ihtimali ya da %50 ye varan orta karar bir hayat yaşayacak geliri olma ihtimalinin çok daha yüksek bir olasılık olduğunu düşünerek yaşamanızı tavsiye ederim. 



Go Struct Veri Tipi Yapıları

struct (structure - yapı demek aslında) veri tipi değişkenler içinde birden fazla ve değişik veri tiplerinde değer saklamak mümkündür. Array bir çok aynı veri tipinde değeri tek bir değişkende saklamak için kullanılıyordu, struct ise değişik veri tiplerine sahip birçok değeri bir arada saklamak için kullanılır. 

Veri tabanı tablolarındaki satırlarda yer alan birçok veri tipindeki değeri tek bir kayıt altında birleştirmek için struct kullanılır. 

Go dilinde struct değişken tanımlaması yapılırken type ve struct kelimeleri bir arada kullanılır.

Deyim yapısı :

type struct_ismi struct {
    eleman1 veritipi;
    eleman2 veritipi;
    eleman3 veritipi;
    ...
}

Örnekte elemanları: isim, yaş, ve maaş olan Çalışan değişkeni tanımlaması görülüyor.

type Çalışan struct {
    isim string
    yaş  int
      string
    maaş int
}

Dikkat ederseniz isim ve elemanları string tipi veri içerirken yaş ve maaş elemanları int tipi veri içeriyor. 


Go Struct Elemanlarına Erişmek

Bir struct değişkenin elemanlarına erişmek için struct adı ve eleman adı arsında nokta ( . ) operatörü kullanılır. 

Örnek :

package main

import "fmt"

type Çalışan struct {
    isim string
    yaş  int
      string
    maaş int
}

func main() {
    var kişi1 Çalışan
    var kişi2 Çalışan

    // kişi1 özellikleri
    kişi1.isim = "Ümit"
    kişi1.yaş = 58
    kişi1. = "Mühendis"
    kişi1.maaş = 24000

    // kişi2 özellikleri
    kişi2.isim = "Arzu"
    kişi2.yaş = 42
    kişi2. = "Pazarlama"
    kişi2.maaş = 36000

    // kişi1 bilgilerine ulaş ve yaz
    fmt.Println("İsim: ", kişi1.isim)
    fmt.Println("Yaş: ", kişi1.yaş)
    fmt.Println("İş: ", kişi1.)
    fmt.Println("Maaş: ", kişi1.maaş)

    // kişi2 bilgilerine ulaş ve yaz
    fmt.Println("İsim: ", kişi2.isim)
    fmt.Println("Yaş: ", kişi2.yaş)
    fmt.Println("İş: ", kişi2.)
    fmt.Println("Maaş: ", kişi2.maaş)
}

ve sıonuç:

İsim:  Ümit
Yaş:  58
İş:  Mühendis
Maaş:  24000
İsim:  Arzu
Yaş:  42
İş:  Pazarlama
Maaş:  36000

Hayatın gerçekleri gibi oldu..


Go Struct Değişkeni Argüman Olarak Kullanmak

Struct değişkeni bir fonksiyona argüman olarak da kullanabiliriz. Örnek :

package main

import "fmt"

type Çalışan struct {
    isim string
    yaş  int
      string
    maaş int
}

func main() {
    var kişi1 Çalışan
    var kişi2 Çalışan

    // kişi1 özellikleri
    kişi1.isim = "Ümit"
    kişi1.yaş = 58
    kişi1. = "Mühendis"
    kişi1.maaş = 24000

    // kişi2 özellikleri
    kişi2.isim = "Arzu"
    kişi2.yaş = 42
    kişi2. = "Pazarlama"
    kişi2.maaş = 36000

    // kişi1 bilgilerini fonksiyonla yaz
    kişiYaz(kişi1)

    // kişi2 bilgilerini fonksiyonla yaz
    kişiYaz(kişi2)
}

func kişiYaz(kişi Çalışan) {
    fmt.Println("İsim: ", kişi.isim)
    fmt.Println("Yaş: ", kişi.yaş)
    fmt.Println("İş: ", kişi.)
    fmt.Println("Maaş: ", kişi.maaş)
}

Gördüğümüz üzere diğer herhangi bir değişkeni argüman olarak kullanmaktan farkı yok. 




Go Map Veri Tipi (Eşleşmeler)

Go dilinde map tipindeki değişkenler içlerinde key:value (isim:değer) şeklinde eşleştirilmiş veri çiftleri taşırlar. 

Bir map içindeki her eleman bir isim:değer çiftidir. 

Map içinde birbirinin aynısı olmasına izin verilmeyen ve bir sıraya tabi tutulmayan veri çiftleri bulunur.

Map içindeki elemanların sayısı (veri çiftlerinin sayısı) len() fonksiyonu ile bulunabilir.

Bir map'in default değeri nil'dir (hiçbir şey - boş).

Map'ler arkaplanda yatan bir karma tablonun verilerine referanstır aslında.

Go dilinde map tanımlamanın birçok yöntemi vardır.


Go Dilinde var ve := Kullanarak Map Tanımlama

Deyim yapısı :

    var a = map[KeyType]ValueType{key1:value1, key2:value2,...}
    b := map[KeyType]ValueType{key1:value1, key2:value2,...}


Örnekte Go dilinde map tanımlama gösteriliyor. Kod içinde ve çıktıdaki veri sıralamasına dikkatinizi çekerim.

package main

import "fmt"

func main() {
    var a = map[string]string{"marka": "Ford", "model": "Mustang", "yılı": "1964"}
    b := map[string]int{"Ankara": 1, "İstanbul": 2, "İzmir": 3, "Sakarya": 4}

    fmt.Printf("a\t%v\n", a)
    fmt.Printf("b\t%v\n", b)
}

ve çıktısı :

a       map[marka:Ford model:Mustang yılı:1964]
b       map[Ankara:1 Sakarya:4 İstanbul:2 İzmir:3]

Not : Map elemanları kodda verildiğinden farklı olur amaç en verimli şekilde verileri sıralamaktır.

Mesela şunu deneyelim:

package main

import "fmt"

func main() {
    var a = map[string]string{"marka": "Ford", "Model": "Mustang", "yılı": "1964"}
    b := map[string]int{"Ankara": 1, "Bİstanbul": 2, "Rİzmir": 3, "Sakarya": 4}

    fmt.Printf("a\t%v\n", a)
    fmt.Printf("b\t%v\n", b)
}

çıktısı :

a       map[Model:Mustang marka:Ford yılı:1964]
b       map[Ankara:1 Bİstanbul:2 Rİzmir:3 Sakarya:4]

Sanırım key değerlerine göre kolay arama yapmak için harf sıralaması ile kaydediliyor.


Go make() Fonksiyonu ile Map Tanımlama

Deyim yapısı :

var a = make(map[KeyType]ValueType)
b := make(map[KeyType]ValueType)


Örnekte make() fonksiyonu ile map tanımlaması gösteriliyor.

package main

import "fmt"

func main() {
    var a = make(map[string]string) // şu anda a nil değerde
    a["marka"] = "Ford"
    a["model"] = "Mustang"
    a["yılı"] = "1964"
    // artık a değeri boş değil
    b := make(map[string]int)
    b["Ankara"] = 1
    b["İstanbul"] = 2
    b["İzmir"] = 3
    b["Sakarya"] = 4

    fmt.Printf("a\t%v\n", a)
    fmt.Printf("b\t%v\n", b)
}



Go Boş Bir Map Tanımlamak

Boş bir map tanımlamanın iki yolu vardır. Biri az önce örnekte gördüğümüz make() fonksiyonu kullanarak, diğeri de aşağıdaki gibi.

var a map[KeyType]ValueType

Not : Bir boş map tanımlamanın doğru yolu make() fonksiyonu kullanmaktır, diğer şekillerde tanımlanmış boş map'ler aslında boş değil nil değere sahiptir. Nil boş demek değil hiç olmayan şey demektir ve bu şekilde tanımlanan bir map'e yazmaya kalkarsanız program çalışma zamanında hata verir (buna Go dilinde runtime panic deniyor).

Örnek verelim.

package main

import "fmt"

func main() {
    var a = make(map[string]string)
    var b map[string]string

    fmt.Println(a == nil)
    fmt.Println(b == nil)
}

çıktısı :

false
true

Gördüğümüz gibi make() ile tanımlanan , nil değil. Şöyle düşünün a değişkeninin içinde değer yok ama en azından map olarak hafızada yer ayrılmış ve değerleri yok, ama b değişkenin sadece adı var gerisi yok.

Deneyip hatayı görelim, yani b değişkenine değer çifti girmeye çalışalım.

package main

import "fmt"

func main() {
    var a = make(map[string]string)
    var b map[string]string

    b["dnm"] = "dnm"
    fmt.Println(a == nil)
    fmt.Println(b == nil)
}

çıktıdaki hata mesajı :

> go run ./maps.go
panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
        /root/go/maps.go:9 +0x58
exit status 2

İşimize yaramayacak bir tanımlama şeklini de niye bu kadar inceledik, bilemiyorum.


İzin Verilen Key Veri Tipleri

Map key değerleri eşitlik (==) işlemini kullanabilen herhangi bir veri tipinde olabilir. 

  • Boolean
  • Sayı
  • String
  • Array
  • Pointer
  • Struct
  • Interface (eğer dinamik veri tipi eşitlik işlemi kullanabiliyorsa)


Geçersiz olan veri tipleri ise :

  • Slice
  • Map
  • Fonksiyon

Bu veri tipleri geçersiz , çünkü bunlarda (==) işlemi uygulanamaz. Demek ki map içinde key araması yapılırken arka planda eşitlik karşılaştırması kullanılıyor.


İzin Verilen Value (değer) Veri Tipleri

Herhangi bir veri tipinde değer kullanılabilir.



Go Map Elemanlarına Erişmek

Map elemanlarına array gibi köşeli parantez yardımıyla erişilir.

Deyim yapısı :

değer = map_adı[key]

Örnek :

package main

import "fmt"

func main() {
    var a = make(map[string]string)
    a["marka"] = "Ford"
    a["model"] = "Mustang"
    a["yılı"] = "1964"

    fmt.Println(a["marka"])
}

çıktısı :

Ford



Map Elemanı Değeri Değiştirme veya Yeni Değer Girme

Deyim yapısı :

map_adı[key] = değer


Örnekte map elemanlarına değer girilmesi görülüyor.

package main

import "fmt"

func main() {
    var a = make(map[string]string)
    a["marka"] = "Ford"
    a["model"] = "Mustang"
    a["yılı"] = "1964"

    fmt.Println(a)

    a["yılı"] = "1970"     // değer değiştirmesi
    a["rengi"] = "kırmızı" // yeni eleman eklenmesi

    fmt.Println(a)
}

ve çıktısı :

map[marka:Ford model:Mustang yılı:1964]
map[marka:Ford model:Mustang rengi:kırmızı yılı:1970]



Go Map Elemanını Silmek

Bir map elemanını yok etmek için delete() fonksiyonu kullanılır.

Deyim yapısı :

delete(map_adı, key)

Örnek :

package main

import "fmt"

func main() {
    var a = make(map[string]string)
    a["marka"] = "Ford"
    a["model"] = "Mustang"
    a["yılı"] = "1964"

    fmt.Println(a)

    delete(a, "yılı")

    fmt.Println(a)
}

ve çıktısı :

map[marka:Ford model:Mustang yılı:1964]
map[marka:Ford model:Mustang]


Go Map İçinde Eleman Sorgulamak

Bir elemanın map içinde olduğunu aşağıdaki şekilde sorgularsınız:

değer, ok := map_adı[key]

Eğer sadece elemanın varlığını (ok) test etmek istersek değer değişkeni yerine alt çizgi ( _ ) gireriz.

Örnek :

package main

import "fmt"

func main() {
    var a = map[string]string{"marka": "Ford", "model": "Mustang", "yılı": "1964", "gün": ""}

    val1, ok1 := a["marka"] // olan bir key ve değerini test etmek
    val2, ok2 := a["renk"]  // olmayan bir key ve değerini test etmek
    val3, ok3 := a["gün"]   // olan bir key ve değerini test etmek
    _, ok4 := a["model"]    // sadece olan bir key , ama değerini test etmemek

    fmt.Println(val1, ok1)
    fmt.Println(val2, ok2)
    fmt.Println(val3, ok3)
    fmt.Println(ok4)
}

çıktısı :

Ford true
 false
 true
true

Bu örnekte map içinde farklı key'leri sorguladık.

Map içinde "renk" key'i yok bu yüzden değeri boş string ( "" ) olarak gelir.

ok2 değişkeni "renk" key'inin map içinde olmasını sorgular ve olmadığı içinde false değerini alır. Bu değişken kullanarak map içinde  bu key'in olmadığını anlıyoruz.


Go Map'ler Aslında Referansdır

Go dilinde map değişkenler aslında map elemanlarının bulunduğu arka plandaki karma bir tablonun hafıza bölgesini işaret eden referanslardır

Eğer iki map değişkeni birbirine eşitlersek aslında iki değişkeninde gösterdiği (referans olduğu) hafıza bölgesini eşitleriz. Bu durumda değişkenlerin birinde yapacağımız değişiklik diğerine aynen yansıyacaktır.

 Örnek verelim :

package main

import "fmt"

func main() {
    var a = map[string]string{"marka": "Ford", "model": "Mustang", "yılı": "1964"}
    b := a

    fmt.Println(a)
    fmt.Println(b)

    b["yılı"] = "1970"
    fmt.Println("b'yi değiştirdikten sonra:")

    fmt.Println(a)
    fmt.Println(b)
}

çıktısı :

map[marka:Ford model:Mustang yılı:1964]
map[marka:Ford model:Mustang yılı:1964]
b'yi değiştirdikten sonra:
map[marka:Ford model:Mustang yılı:1970]
map[marka:Ford model:Mustang yılı:1970]



Go Map Elemanlarında İterasyon Yapmak

range kelimesini kullanarak map elemanları üzerinde iterasyon yapılır.

Örnekte bir map elemanları üzerinde iterasyon yapılması gösteriliyor. Çıktıdaki sıralamaya dikkat ediniz.

package main

import "fmt"

func main() {
    a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}

    for k, v := range a {
        fmt.Printf("%v : %v, ", k, v)
    }
    fmt.Printf("\n%v\n", a)
}

çıktısı : 

one : 1, two : 2, three : 3, four : 4,
map[four:4 one:1 three:3 two:2]



Go Map Elemanlarında Belirlenen Sırada İterasyon

Map'ler sıralanmamış veri yapılarıdır. Eğer istediğiniz sırada verilerin üzerinde iterasyon yapmak isteseniz sıralamayı ayrı bir yapıda bildirmeniz gerekir.

Örnek :

package main

import "fmt"

func main() {
    a := map[string]int{"two": 2, "three": 3, "four": 4, "one": 1}

    var b []string      // sıralamayı belirten array
    b = append(b, "one", "two", "three", "four")

    for k, v := range a {   // sıralamasız iterasyon
        fmt.Printf("%v : %v, ", k, v)
    }

    fmt.Println()

    for _,eleman := range b { // istenen sıralama ile iterasyon
        fmt.Printf("%v : %v, ", eleman, a[eleman])
    }
}

çıktısı :

four : 4, one : 1, two : 2, three : 3,
one : 1, two : 2, three : 3, four : 4,


Buraya kadar Go dilinin temel tekniklerini gördük , umarım daha gelişmiş deneyimlerde buluşuruz.

Şimdilik kalın sağlıcakla..








Hiç yorum yok:

Yorum Gönder