Golang Eğitimi: Yeni Başlayanlar İçin Go Programlama Dilini Öğrenin

Git nedir?

Go (Golang olarak da bilinir) Google tarafından geliştirilen açık kaynaklı bir programlama dilidir. Statik olarak yazılmış derlenmiş bir dildir. Go eş zamanlı programlamayı destekler, yani birden fazla işlemi aynı anda çalıştırmaya izin verir. Bu, kanallar, goroutines vb. kullanılarak elde edilir. Go Dili, bellek yönetimini kendisi yapan ve işlevlerin ertelenmiş yürütülmesine izin veren çöp toplama özelliğine sahiptir.

Bu Learn Go Dil Eğitiminde Golang'ın tüm temellerini öğreneceğiz.

GO nasıl indirilir ve yüklenir

) 1 Adım MyCAD'de yazılım Güncelleme ye git https://golang.org/dl/. İşletim sisteminize uygun ikili dosyayı indirin.

) 2 Adım Double yükleyiciye tıklayın ve Çalıştır'a tıklayın.

) 3 Adım İleri'yi tıklayın

) 4 Adım Kurulum klasörünü seçin ve İleri'ye tıklayın.

) 5 Adım Kurulum tamamlandıktan sonra Son'a tıklayın.

) 6 Adım Kurulum tamamlandıktan sonra terminali açıp şunu yazarak doğrulayabilirsiniz:

go version

Bu, go'nun yüklü sürümünü gösterecektir

İlk Git programınız – Git Merhaba Dünya!

StudyGo adında bir klasör oluşturun. Bu Go dili eğitiminde go programlarımızı bu klasörün içinde oluşturacağız. Go dosyaları uzantıyla oluşturulur .Git. Go programlarını sözdizimini kullanarak çalıştırabilirsiniz.

go run <filename>

First.go adında bir dosya oluşturun ve içine aşağıdaki kodu ekleyin ve kaydedin.

package main
import ("fmt")

func main() {
	fmt.Println("Hello World! This is my first Go program\n")
}

Terminalinizde bu klasöre gidin. Komutu kullanarak programı çalıştırın

önce git koş. git

Çıktı yazdırmayı görebilirsiniz

Hello World! This is my first Go program

Şimdi yukarıdaki programı tartışalım.

paket ana – Her Go Language programı bir paket adıyla başlamalıdır. Go, paketleri başka bir go programında kullanmamıza olanak tanır ve dolayısıyla kodun yeniden kullanılabilirliğini destekler. Bir Go programının çalıştırılması, main adlı paketin içindeki kodla başlar.

import fmt – fmt paketini içe aktarır. Bu paket G/Ç işlevlerini uygular.

func main() – Bu, program yürütmenin başladığı işlevdir. Ana işlev her zaman ana pakete yerleştirilmelidir. Main() altında, kodu { } içine yazabilirsiniz.

fmt.Println – Bu, metni fmt'nin Println işleviyle ekrana yazdıracaktır.

Not: Bu Go eğitiminin aşağıdaki bölümlerinde, kodu çalıştırmak/çalıştırmaktan bahsettiğinizde, bu, kodu .go uzantılı bir dosyaya kaydetmek ve sözdizimini kullanarak çalıştırmak anlamına gelir.

    go run <filename>

Veri tipleri

Türler (veri türleri), bir değişkende saklanan değerin türünü, bir işlevin döndürdüğü değerin türünü vb. temsil eder.

Go Dilinde üç temel tür vardır

Sayısal tipler – Tam sayı, kayan nokta ve karmaşık değerleri içeren sayısal değerleri temsil eder. Çeşitli sayısal türler şunlardır:

int8 – 8 bitlik işaretli tamsayılar.

int16 – 16 bitlik işaretli tamsayılar.

int32 – 32 bitlik işaretli tamsayılar.

int64 – 64 bitlik işaretli tamsayılar.

uint8 – 8 bitlik işaretsiz tamsayılar.

uint16 – 16 bitlik işaretsiz tamsayılar.

uint32 – 32 bitlik işaretsiz tamsayılar.

uint64 – 64 bitlik işaretsiz tamsayılar.

float32 – 32 bit kayan noktalı sayılar.

float64 – 64 bit kayan noktalı sayılar.

complex64 – float32 reel ve sanal kısımlara sahiptir.

complex128 – float32 reel ve sanal kısımlara sahiptir.

dize türleri – Bir bayt (karakter) dizisini temsil eder. Dize birleştirme, alt dize çıkarma vb. gibi dizeler üzerinde çeşitli işlemler yapabilirsiniz.

Boole türleri – Doğru veya yanlış olmak üzere 2 değeri temsil eder.

Golang Arayüzü

Golang Arayüzü Nesnelerin davranışını uygulamak için bir Tür tarafından kullanılan yöntem imzalarının bir koleksiyonudur. Golang arayüzünün temel amacı, adlar, argümanlar ve dönüş türleriyle birlikte yöntem imzaları sağlamaktır. Yöntemi bildirmek ve uygulamak bir Tip'e bağlıdır. Golang'da bir arayüz "arayüz" anahtar kelimesi kullanılarak bildirilebilir.

Değişkenler

Değişkenler, bir tür değeri saklayan bir hafıza konumuna işaret eder. Type parametresi (aşağıdaki sözdiziminde), bellek konumunda saklanabilecek değer türünü temsil eder.

Değişken sözdizimi kullanılarak bildirilebilir

    var <variable_name> <type>

Bir tür değişkeni bildirdikten sonra, değişkeni o türdeki herhangi bir değere atayabilirsiniz.

Ayrıca bildirimin kendisi sırasında bir değişkene bir başlangıç ​​değeri de verebilirsiniz.

    var <variable_name> <type> = <value>

Değişkeni bir başlangıç ​​değeriyle bildirirseniz, atanan değerin türünden değişkenin türünü çıkarın. Yani sözdizimini kullanarak bildirim sırasında türü atlayabilirsiniz.

    var <variable_name> = <value>

Ayrıca söz dizimi ile birden fazla değişken bildirebilirsiniz.

    var <variable_name1>, <variable_name2>  = <value1>, <value2>

Bu Go eğitimindeki aşağıdaki programda değişken bildirimlerinin bazı Golang örnekleri bulunmaktadır.

 
package main
import "fmt"

func main() {
    //declaring a integer variable x
    var x int
    x=3 //assigning x the value 3 
    fmt.Println("x:", x) //prints 3
    
    //declaring a integer variable y with value 20 in a single statement and prints it
    var y int=20
    fmt.Println("y:", y)
    
    //declaring a variable z with value 50 and prints it
    //Here type int is not explicitly mentioned 
    var z=50
    fmt.Println("z:", z)
    
    //Multiple variables are assigned in single line- i with an integer and j with a string
    var i, j = 100,"hello"
    fmt.Println("i and j:", i,j)
}

Çıktı olacak

x: 3
y: 20
z: 50
i and j: 100 hello

Go Language ayrıca var anahtar sözcüğünü atlayarak değişkenleri değerle bildirmenin kolay bir yolunu sağlar.

    <variable_name> := <value>

Kullandığınızı unutmayın := yerine =. := komutunu yalnızca önceden bildirilmiş bir değişkene değer atamak için kullanamazsınız. := değeri bildirmek ve atamak için kullanılır.

Aşağıdaki kodla assign.go adında bir dosya oluşturun

package main
import ("fmt")

func main() {
	a := 20
	fmt.Println(a)

	//gives error since a is already declared
	a := 30
	fmt.Println(a)
}

Sonucu aşağıdaki gibi görmek için go run quest.go komutunu çalıştırın.

./assign.go:7:4: no new variables on left side of :=		

Başlangıç ​​değeri olmadan bildirilen değişkenler sayısal türler için 0, Boolean için false ve dizeler için boş dizeye sahip olacaktır.

Sabitler

Sabit değişkenler, atandıktan sonra değeri değiştirilemeyen değişkenlerdir. Go programlama dilinde bir sabit “const” anahtar sözcüğü kullanılarak bildirilir.

constant.go adında bir dosya oluşturun ve aşağıdaki kodu ekleyin

package main
import ("fmt")

func main() {
	const b =10
	fmt.Println(b)
	b = 30
	fmt.Println(b)
}

Sonucu aşağıdaki gibi görmek için go run consbit.go komutunu çalıştırın.

.constant.go:7:4: cannot assign to b

Döngü Örnekleri İçin

Döngüler, bir koşula bağlı olarak bir ifade bloğunu tekrar tekrar yürütmek için kullanılır. Çoğu programlama dili 3 tür döngü sağlar; for, while, do while. Ancak Go programlama dili yalnızca for döngüsünü destekler.

Golang for döngüsünün sözdizimi şu şekildedir:

for initialisation_expression; evaluation_expression; iteration_expression{
   // one or more statement
}

Başlatma_ifadesi Golang for döngüsünde ilk önce (ve yalnızca bir kez) yürütülür.

Daha sonra değerlendirme_ifadesi değerlendirilir ve eğer doğruysa bloğun içindeki kod yürütülür.

iteration_expression kimliği yürütülür ve değerlendirme_ifadesi yeniden değerlendirilir. Eğer bu doğruysa, ifade bloğu tekrar yürütülür. Bu, değerlendirme_ifadesi yanlış olana kadar devam edecektir.

Aşağıdaki programı bir dosyaya kopyalayın ve 1'den 5'e kadar döngü yazdırma sayıları için Golang'ı görmek için çalıştırın.

package main
import "fmt"

func main() {  
var i int
for i = 1; i <= 5; i++ {
fmt.Println(i)
    }
}

Çıktı

1
2
3
4
5

Aksi halde

If else koşullu bir ifadedir. Sinaks

if condition{
// statements_1
}else{
// statements_2
}

Burada koşul değerlendirilir ve eğer doğruysa ifade_1 yürütülür, aksi takdirde ifade_2 yürütülür.

If ifadesini else olmadan da kullanabilirsiniz. Ayrıca if else ifadelerini de zincirleyebilirsiniz. Aşağıdaki programlar if else hakkında daha fazla bilgi verecektir.

Aşağıdaki programı yürütün. X sayısının 10'dan küçük olup olmadığını kontrol eder. Eğer öyleyse “x 10'dan küçüktür” yazdırır.

package main
import "fmt"

func main() {  
    var x = 50
    if x < 10 {
        //Executes if x < 10
        fmt.Println("x is less than 10")
    } 
}

Burada x'in değeri 10'dan büyük olduğundan if blok koşulunun içindeki ifade yürütülmeyecektir.

Şimdi aşağıdaki programa bakın. Bu Go programlama dili eğitiminde, if değerlendirmesinin başarısız olması durumunda çalıştırılacak bir else bloğumuz var.

package main
import "fmt"

func main() {  
    var x = 50
    if x < 10 {
        //Executes if x is less than 10
        fmt.Println("x is less than 10")
    } else {
        //Executes if x >= 10
        fmt.Println("x is greater than or equals 10")
    }
}

Bu program size çıktı verecektir

x is greater than or equals 10

Şimdi bu Go eğitiminde, birden fazla if else bloğu (zincirlenmiş if else) içeren bir program göreceğiz. Aşağıdaki Go örneğini yürütün. Bir sayının 10'dan küçük, 10-90 arasında veya 90'dan büyük olup olmadığını kontrol eder.

package main
import "fmt"

func main() {  
    var x = 100
    if x < 10 {
        //Executes if x is less than 10
        fmt.Println("x is less than 10")
    } else if x >= 10 && x <= 90 {
        //Executes if x >= 10 and x<=90
        fmt.Println("x is between 10 and 90")
    } else {
        //Executes if both above cases fail i.e x>90
        fmt.Println("x is greater than 90")
    }
}

Burada ilk olarak if koşulu x'in 10'dan küçük olup olmadığını kontrol eder. Böylece bir sonraki koşulun (eğer yoksa) 10 ile 90 arasında olup olmadığını kontrol eder ki bu da yanlıştır. Böylece çıktıyı veren else bölümünün altındaki bloğu çalıştırır.

x is greater than 90

anahtar

Switch başka bir koşullu ifadedir. Switch ifadeleri bir ifadeyi değerlendirir ve sonuç, mevcut değerler (durumlar) kümesiyle karşılaştırılır. Bir eşleşme bulunduğunda, o eşleşmeyle (durum) ilişkili ifadeler yürütülür. Eşleşme bulunamazsa hiçbir şey yürütülmeyecektir. Ayrıca, başka eşleşme bulunmazsa yürütülecek olan anahtara varsayılan bir durum da ekleyebilirsiniz. Anahtarın sözdizimi şöyledir

switch expression {
    case value_1:
        statements_1
    case value_2:
        statements_2
    case value_n:
        statements_n
    default:
        statements_default
    }

Burada ifadenin değeri her durumdaki değerlerle karşılaştırılır. Bir eşleşme bulunduğunda, bu durumla ilişkili ifadeler yürütülür. Eşleşme bulunamazsa, varsayılan bölüm altındaki ifadeler yürütülür.

Aşağıdaki programı yürütün

package main
import "fmt"

func main() {  
    a,b := 2,1
    switch a+b {
    case 1:
        fmt.Println("Sum is 1")
    case 2:
        fmt.Println("Sum is 2")
    case 3:
        fmt.Println("Sum is 3")
    default:
        fmt.Println("Printing default")
    }
}

Çıktıyı şu şekilde alacaksınız:

Sum is 3		

a ve b'nin değerini 3 olarak değiştirin; sonuç şu şekilde olacaktır:

Printing default

Ayrıca bir durumda, virgülle ayırarak birden fazla değere sahip olabilirsiniz.

Diziler

Dizi, aynı türdeki öğelerin adlandırılmış sırasını sabit bir boyutta temsil eder. Hem tam sayı hem de karakter içeren bir diziye sahip olamazsınız. Boyutu tanımladıktan sonra dizinin boyutunu değiştiremezsiniz.

Bir dizi bildirmenin sözdizimi şöyledir

var arrayname [size] type

Her dizi öğesine sözdizimi kullanılarak değer atanabilir

arrayname [index] = value

Dizi dizini şuradan başlar: 0'dan boyut-1'e.

Sözdizimini kullanarak bildirim sırasında dizi öğelerine değer atayabilirsiniz.

arrayname := [size] type {value_0,value_1,…,value_size-1} 

Ayrıca, size ile değiştirerek diziyi değerlerle bildirirken size parametresini de göz ardı edebilirsiniz. ... ve derleyici değerlerin sayısından uzunluğu bulacaktır. Sözdizimi:

arrayname :=  […] type {value_0,value_1,…,value_size-1}

Sözdizimini kullanarak dizinin uzunluğunu bulabilirsiniz.

len(arrayname)

Diziyi anlamak için aşağıdaki Go örneğini yürütün

package main
import "fmt"

func main() {  
    var numbers [3] string //Declaring a string array of size 3 and adding elements 
    numbers[0] = "One"
    numbers[1] = "Two"
    numbers[2] = "Three"
    fmt.Println(numbers[1]) //prints Two
    fmt.Println(len(numbers)) //prints 3
    fmt.Println(numbers) // prints [One Two Three]

    directions := [...] int {1,2,3,4,5} // creating an integer array and the size of the array is defined by the number of elements 
    fmt.Println(directions) //prints [1 2 3 4 5]
    fmt.Println(len(directions)) //prints 5

    //Executing the below commented statement prints invalid array index 5 (out of bounds for 5-element array)
    //fmt.Println(directions[5]) 
}

Çıktı

Two
3
[One Two Three]
[1 2 3 4 5]
5

Golang Dilimleme ve Ekleme İşlevi

Dilim, bir dizinin bir kısmı veya bölümüdür. Veya işaret ettiği temel dizinin görünümü veya kısmi görünümüdür. Bir dizide yaptığınız gibi, dilim adını ve dizin numarasını kullanarak bir dilimin öğelerine erişebilirsiniz. Bir dizinin uzunluğunu değiştiremezsiniz ancak bir dilimin boyutunu değiştirebilirsiniz.

Bir dilimin içeriği aslında bir dizinin öğelerinin işaretçileridir. Anlamı bir dilimdeki herhangi bir öğeyi değiştirirseniz, temeldeki dizi içerikleri de etkilenecektir.

Dilim oluşturmanın sözdizimi şöyledir:

var slice_name [] type = array_name[start:end]

Bu, dizi_adı adlı bir diziden, dizindeki öğelerin başından 1'e kadar olduğu dilim_adı adlı bir dilim yaratacaktır.

Şimdi bu Golang eğitiminde aşağıdaki programı uygulayacağız. Program diziden bir dilim oluşturacak ve onu yazdıracaktır. Ayrıca dilimdeki içeriği değiştirmenin gerçek diziyi de değiştireceğini görebilirsiniz.

package main
import "fmt"

func main() {  
    // declaring array
    a := [5] string {"one", "two", "three", "four", "five"}
    fmt.Println("Array after creation:",a)

    var b [] string = a[1:4] //created a slice named b
    fmt.Println("Slice after creation:",b)

    b[0]="changed" // changed the slice data
    fmt.Println("Slice after modifying:",b)
    fmt.Println("Array after slice modification:",a)
}

Bu, sonucu şu şekilde yazdıracaktır:

Array after creation: [one two three four five]
Slice after creation: [two three four]
Slice after modifying: [changed three four]
Array after slice modification: [one changed three four five]

Dilimlere uygulayabileceğiniz Golang len, Golang eklentisi gibi belirli işlevler vardır.

len(dilim_adı) – dilimin uzunluğunu döndürür

ekleme(dilim_adı, değer_1, değer_2) – Golang ekleme, değer_1 ve değer_2'yi mevcut bir dilime eklemek için kullanılır.

ekleme(dilim_nale1,dilim_adı2…) – dilim_adı2'yi dilim_adı1'e ekler

Aşağıdaki programı çalıştırın.

package main
import "fmt"

func main() {  
	a := [5] string {"1","2","3","4","5"}
	slice_a := a[1:3]
	b := [5] string {"one","two","three","four","five"}
	slice_b := b[1:3]

    fmt.Println("Slice_a:", slice_a)
    fmt.Println("Slice_b:", slice_b)
    fmt.Println("Length of slice_a:", len(slice_a))
    fmt.Println("Length of slice_b:", len(slice_b))

    slice_a = append(slice_a,slice_b...) // appending slice
    fmt.Println("New Slice_a after appending slice_b :", slice_a)
    
    slice_a = append(slice_a,"text1") // appending value
    fmt.Println("New Slice_a after appending text1 :", slice_a)
}

Çıktı olacak

Slice_a: [2 3]
Slice_b: [two three]
Length of slice_a: 2
Length of slice_b: 2
New Slice_a after appending slice_b : [2 3 two three]
New Slice_a after appending text1 : [2 3 two three text1]

Program öncelikle 2 dilim oluşturup uzunluğunu yazdırıyor. Daha sonra bir dilim diğerine eklendi ve ardından ortaya çıkan dilime bir dize eklendi.

fonksiyonlar

Bir işlev, belirli bir görevi gerçekleştiren bir ifade bloğunu temsil eder. Bir işlev bildirimi bize işlevin adını, dönüş türünü ve giriş parametrelerini bildirir. Fonksiyon tanımı, fonksiyonun içerdiği kodu temsil eder. İşlevi bildirmenin sözdizimi şöyledir:

func function_name(parameter_1 type, parameter_n type) return_type {
//statements
}

Parametreler ve dönüş türleri isteğe bağlıdır. Ayrıca bir fonksiyondan birden fazla değer döndürebilirsiniz.

Şimdi bu Golang eğitiminde, aşağıdaki Golang örneğini çalıştıralım. Burada calc adlı fonksiyon 2 sayıyı kabul edecek ve toplama ve çıkarma işlemini gerçekleştirecek ve her iki değeri de döndürecektir.

package main
import "fmt"

//calc is the function name which accepts two integers num1 and num2
//(int, int) says that the function returns two values, both of integer type.
func calc(num1 int, num2 int)(int, int) {  
    sum := num1 + num2
    diff := num1 - num2
    return sum, diff
}

func main() {  
    x,y := 15,10

    //calls the function calc with x and y an d gets sum, diff as output
    sum, diff := calc(x,y) 
    fmt.Println("Sum",sum)
    fmt.Println("Diff",diff) 
}

Çıktı olacak

Sum 25
Diff 5

Paketler

Paketler kodu düzenlemek için kullanılır. Büyük bir projede tek bir dosyaya kod yazmak mümkün değildir. Go programlama dili, kodu farklı paketler altında düzenlememize olanak tanır. Bu, kodun okunabilirliğini ve yeniden kullanılabilirliğini artırır. Yürütülebilir bir Go programı main adlı bir paket içermeli ve programın yürütülmesi main adlı işlevden başlamalıdır. Sözdizimini kullanarak programımızdaki diğer paketleri içe aktarabilirsiniz.

import package_name

Bu Golang eğitiminde, aşağıdaki Golang örneğinde paketlerin nasıl oluşturulacağını ve kullanılacağını göreceğiz ve tartışacağız.

) 1 Adım package_example.go adında bir dosya oluşturun ve aşağıdaki kodu ekleyin

package main
import "fmt"
//the package to be created
import "calculation"

func main() {  
	x,y := 15,10
	//the package will have function Do_add()
sum := calculation.Do_add(x,y)
fmt.Println("Sum",sum) 
}

Yukarıdaki programda fmt, Go programlama dilinin bize esas olarak I/O amacıyla sağladığı bir pakettir. Ayrıca hesaplama adlı bir paket görebilirsiniz. main() içinde bir adım toplamı görebilirsiniz:= hesaplama.Do_add(x,y). Bu, paket hesaplamasından Do_add fonksiyonunu çağırdığınız anlamına gelir.

) 2 Adım Öncelikle paket hesaplamasını go'nun src klasörü altında aynı isimli bir klasör içerisinde oluşturmalısınız. Kurulu go yolunu PATH değişkeninden bulabilirsiniz.

Mac için echo $PATH komutunu çalıştırarak yolu bulun

Yani yol /usr/local/go

Windows için, echo %GOROOT% komutunu çalıştırarak yolu bulun

İşte yol C:\Go\

) 3 Adım src klasörüne gidin (/usr/local/go/src mac için ve C:\Go\src windows için). Şimdi koddan, paket adı accounting. Go, paketin src dizini altında aynı adlı bir dizine yerleştirilmesini gerektirir. src klasöründe accounting adlı bir dizin oluşturun.

) 4 Adım Hesaplama dizinine calc.go adında bir dosya oluşturun (Herhangi bir isim verebilirsiniz ama koddaki paket ismi önemli. Burada hesaplama olmalı) ve aşağıdaki kodu ekleyin.

package calculation
  
func Do_add(num1 int, num2 int)(int) {
    sum := num1 + num2
    return sum
}

) 5 Adım calc.go'yu derleyecek hesaplama dizininden go install komutunu çalıştırın.

) 6 Adım Şimdi package_example.go'ya geri dönün ve go run package_example.go'yu çalıştırın. Çıktı Toplam 25 olacaktır.

Do_add fonksiyonunun adının büyük harfle başladığına dikkat edin. Bunun nedeni, Go'da işlev adı büyük harfle başlıyorsa, bu, diğer programların görebileceği (erişebileceği), aksi halde diğer programların ona erişemeyeceği anlamına gelir. İşlev adı do_add olsaydı, o zaman hatayı alırdın

dışa aktarılmamış ad hesaplama.hesabına başvurulamaz.

Erteleme ve yığınlama ertelemeleri

Defer ifadeleri, defer ifadesini içeren işlev yürütmeyi tamamlayana kadar bir işlev çağrısının yürütülmesini ertelemek için kullanılır.

Bunu bir örnekle öğrenelim:

package main
import "fmt"

func sample() {  
    fmt.Println("Inside the sample()")
}
func main() {  
    //sample() will be invoked only after executing the statements of main()
    defer sample()
    fmt.Println("Inside the main()")
}

Çıktı olacak

Inside the main()
Inside the sample()

Burada sample()'ın yürütülmesi, çevreleyen işlevin (main()) yürütülmesi tamamlanana kadar ertelenir.

Yığınlama erteleme, birden fazla erteleme ifadesi kullanmaktır. Bir fonksiyonun içinde birden fazla defer ifadeniz olduğunu varsayalım. Go, tüm ertelenmiş işlev çağrılarını bir yığına yerleştirir ve çevreleyen işlev geri döndüğünde, yığınlanmış işlevler yığında yürütülür. Son Giren İlk Çıkar (LIFO) sırası. Aşağıdaki örnekte bunu görebilirsiniz.

Aşağıdaki kodu yürütün

package main
import "fmt"

func display(a int) {  
    fmt.Println(a)
}
func main() {  
    defer display(1)
    defer display(2)
    defer display(3)
    fmt.Println(4)
}

Çıktı olacak

4
3
2
1			

Burada ilk önce main() içindeki kod çalıştırılır ve ardından ertelenen işlev çağrıları ters sırada, yani 4, 3,2,1 yürütülür.

İşaretçiler

İşaretçileri açıklamadan önce '&' operatöründen bahsedelim. '&' operatörü bir değişkenin adresini almak için kullanılır. Bu, '&a'nın a değişkeninin bellek adresini yazdıracağı anlamına gelir.

Bu Golang eğitiminde, bir değişkenin değerini ve o değişkenin adresini görüntülemek için aşağıdaki programı çalıştıracağız.

package main
import "fmt"

func main() {
	a := 20
	fmt.Println("Address:",&a)
	fmt.Println("Value:",a)
}

Sonuç olacak

Address: 0xc000078008
Value: 20

Bir işaretçi değişkeni, başka bir değişkenin bellek adresini saklar. Sözdizimini kullanarak bir işaretçi tanımlayabilirsiniz

	var variable_name *type

Yıldız işareti (*), değişkenin bir işaretçi olduğunu temsil eder. Aşağıdaki programı çalıştırdığınızda daha iyi anlayacaksınız

package main
import "fmt"

func main() {
	//Create an integer variable a with value 20
	a := 20
	
	//Create a pointer variable b and assigned the address of a
	var b *int = &a

	//print address of a(&a) and value of a  
	fmt.Println("Address of a:",&a)
	fmt.Println("Value of a:",a)

	//print b which contains the memory address of a i.e. &a
	fmt.Println("Address of pointer b:",b)

	//*b prints the value in memory address which b contains i.e. the value of a
	fmt.Println("Value of pointer b",*b)

	//increment the value of variable a using the variable b
	*b = *b+1

	//prints the new value using a and *b
	fmt.Println("Value of pointer b",*b)
	fmt.Println("Value of a:",a)}

Çıktı olacak

Address of a: 0x416020
Value of a: 20
Address of pointer b: 0x416020
Value of pointer b 20
Value of pointer b 21
Value of a: 21

yapılar

Yapı, kendisi aynı veya farklı türden bir öğe daha içeren, kullanıcı tanımlı bir veri türüdür.

Bir yapıyı kullanmak 2 adımlı bir süreçtir.

İlk önce bir yapı türü oluşturun (bildirin)

İkinci olarak, değerleri depolamak için bu türden değişkenler oluşturun.

Yapılar çoğunlukla ilgili verileri bir arada depolamak istediğinizde kullanılır.

Adı, yaşı ve adresi olan bir çalışan bilgisini düşünün. Bunu 2 şekilde halledebilirsiniz

3 dizi oluşturun; bir dizi çalışanların adlarını, bir dizi yaşını ve üçüncüsü ise yaşını saklar.

Ad, adres ve yaş olmak üzere 3 alanlı bir yapı türü bildirin. Her öğenin adı, adresi ve yaşı olan bir yapı nesnesi olduğu bu yapı türünden bir dizi oluşturun.

İlk yaklaşım etkili değildir. Bu tür senaryolarda yapılar daha uygundur.

Bir yapıyı bildirmenin sözdizimi şöyledir:

type structname struct {
   variable_1 variable_1_type
   variable_2 variable_2_type
   variable_n variable_n_type
}

Bir yapı bildirimi örneği:

type emp struct {
    name string
    address string
    age int
}

Burada emp adında yeni bir kullanıcı tanımlı tür oluşturulur. Artık sözdizimini kullanarak emp türünde değişkenler oluşturabilirsiniz.

	var variable_name struct_name

Bir örnek

var empdata1 emp 

Emdata1 için değerleri şu şekilde ayarlayabilirsiniz:

empdata1.name = "John"
	empdata1.address = "Street-1, Bangalore"
	empdata1.age = 30

Ayrıca bir yapı değişkeni oluşturabilir ve değerleri şu şekilde atayabilirsiniz:

empdata2 := emp{"Raj", "Building-1, Delhi", 25}

Burada elemanların sırasını korumanız gerekiyor. Raj isimle, sonraki öğeyle adresle ve son öğenin yaşıyla eşleştirilecek.

Aşağıdaki kodu yürütün

package main
import "fmt"

//declared the structure named emp
type emp struct {
        name string
        address string
        age int
}       

//function which accepts variable of emp type and prints name property
func display(e emp) {
          fmt.Println(e.name)
}

func main() {
// declares a variable, empdata1, of the type emp
var empdata1 emp
//assign values to members of empdata1
empdata1.name = "John"
empdata1.address = "Street-1, London"
empdata1.age = 30

//declares and assign values to variable empdata2 of type emp
empdata2 := emp{"Raj", "Building-1, Paris", 25}

//prints the member name of empdata1 and empdata2 using display function
display(empdata1)
display(empdata2)
}

Çıktı

John
Raj

Yöntemler (işlevler değil)

Yöntem, alıcı argümanına sahip bir işlevdir. Archiyapısal olarak func anahtar sözcüğü ile yöntem adı arasındadır. Bir yöntemin sözdizimi

func (variable variabletype) methodName(parameter1 paramether1type) {  
}

Yukarıdaki örnek programı işlev yerine yöntemleri kullanacak şekilde dönüştürelim.

package main
import "fmt"

//declared the structure named emp
type emp struct {
    name string
    address string
    age int
}

//Declaring a function with receiver of the type emp
func(e emp) display() {
    fmt.Println(e.name)
}

func main() {
    //declaring a variable of type emp
    var empdata1 emp
    
    //Assign values to members
    empdata1.name = "John"
    empdata1.address = "Street-1, Lodon"
    empdata1.age = 30

    //declaring a variable of type emp and assign values to members
    empdata2 := emp {
        "Raj", "Building-1, Paris", 25}

    //Invoking the method using the receiver of the type emp
   // syntax is variable.methodname()
    empdata1.display()
    empdata2.display()
}

Go nesne yönelimli bir dil değildir ve sınıf kavramına sahip değildir. Yöntemler, bir sınıfın işlevlerinin objectname.functionname() sözdizimi kullanılarak çağrıldığı nesne yönelimli programlarda ne yaptığınıza dair bir fikir verir.

eşzamanlılık

Go görevlerin eş zamanlı yürütülmesini destekler. Bu, Go'nun birden fazla görevi eş zamanlı olarak yürütebileceği anlamına gelir. Bu, paralellik kavramından farklıdır. Paralellikte, bir görev küçük alt görevlere bölünür ve paralel olarak yürütülür. Ancak eşzamanlılıkta, birden fazla görev eş zamanlı olarak yürütülür. Eş zamanlılık, Go'da Goroutines ve Channels kullanılarak elde edilir.

Goroutinler

Goroutine, diğer işlevlerle eşzamanlı olarak çalışabilen bir işlevdir. Genellikle bir fonksiyon çağrıldığında kontrol çağrılan fonksiyona aktarılır ve yürütme kontrolü tamamlandığında çağıran fonksiyona geri döner. Çağıran işlev daha sonra yürütülmesine devam eder. Çağıran işlev, çağrılan işlevin geri kalan ifadelere devam etmeden önce yürütmeyi tamamlamasını bekler.

Ancak goroutine durumunda, çağıran fonksiyon, çağrılan fonksiyonun yürütülmesinin tamamlanmasını beklemeyecektir. Sonraki ifadelerle çalışmaya devam edecektir. Bir programda birden fazla goroutine sahip olabilirsiniz.

Ayrıca ana program, ifadelerini yürütmeyi tamamladıktan sonra çıkacak ve çağrılan goroutinlerin tamamlanmasını beklemeyecektir.

Goroutine, go anahtar sözcüğü ve ardından bir işlev çağrısı kullanılarak çağrılır.

Örnek E-posta

go add(x,y)

Aşağıdaki Golang örnekleriyle goroutinleri anlayacaksınız. Aşağıdaki programı yürütün

package main
import "fmt"
    
func display() {
	for i:=0; i<5; i++ {
		fmt.Println("In display")
	}
}

func main() {
	//invoking the goroutine display()
	go display()
	//The main() continues without waiting for display()
	for i:=0; i<5; i++ {
		fmt.Println("In main")
	}
}

Çıktı olacak

In main
In main
In main
In main
In main

Burada ana program, goroutine başlamadan önce yürütmeyi tamamladı. display() sözdizimi kullanılarak çağrılan bir goroutine'dir.

go function_name(parameter list)

Yukarıdaki kodda main(), display()'in tamamlanmasını beklemez ve main(), display() kodunu çalıştırmadan önce yürütmesini tamamlar. Yani display() içindeki print ifadesi yazdırılmadı.

Şimdi programı display() öğesinden de ifadeleri yazdıracak şekilde değiştiriyoruz. Main()'ın for döngüsüne 2 saniyelik bir zaman gecikmesi ve display()'in for döngüsüne 1 saniyelik bir gecikme ekliyoruz.

package main
import "fmt"
import "time"
    
func display() {
	for i:=0; i<5; i++ {
		time.Sleep(1 * time.Second)
		fmt.Println("In display")
	}
}

func main() {
	//invoking the goroutine display()
	go display()
	for i:=0; i<5; i++ {
		time.Sleep(2 * time.Second)
		fmt.Println("In main")
	}
}

Çıktı biraz benzer olacak

In display
In main
In display
In display
In main
In display
In display
In main
In main
In main

Burada, eşzamanlı yürütme nedeniyle her iki döngünün de örtüşen bir şekilde yürütüldüğünü görebilirsiniz.

Kanallar

Kanallar, fonksiyonların birbirleriyle iletişim kurmasının bir yoludur. Golang sunucusunda bir rutinin verileri yerleştirdiği ve başka bir rutin tarafından erişildiği bir ortam olarak düşünülebilir.

Bir kanal söz dizimi ile bildirilebilir

channel_variable := make(chan datatype)

Örnek:

	ch := make(chan int)

Sözdizimini kullanarak bir kanala veri gönderebilirsiniz

channel_variable <- variable_name

Örnek E-posta

    ch <- x

Sözdizimini kullanarak bir kanaldan veri alabilirsiniz

    variable_name := <- channel_variable

Örnek E-posta

   y := <- ch

Yukarıdaki Go dili goroutine örneklerinde, ana programın goroutine'i beklemediğini gördünüz. Ancak kanallar söz konusu olduğunda durum böyle değildir. Bir goroutine'in verileri kanala ittiğini varsayalım, main() işlevi, verileri alana kadar kanal verilerini alan ifadeyi bekleyecektir.

Bunu aşağıdaki Go dili örneklerinde göreceksiniz. Öncelikle normal bir goroutine yazın ve davranışı görün. Daha sonra programı kanalları kullanacak şekilde değiştirin ve davranışı görün.

Aşağıdaki programı yürütün

package main
import "fmt"
import "time"
    
func display() {
	time.Sleep(5 * time.Second)
	fmt.Println("Inside display()")
}

func main() {
	go display()
	fmt.Println("Inside main()")
}

Çıktı olacak

Inside main()

main() yürütmeyi tamamladı ve goroutine yürütülmeden önce çıktı. Yani display() içindeki baskı yürütülmedi.

Şimdi kanalları kullanmak ve davranışı görmek için yukarıdaki programı değiştirin.

package main
import "fmt"
import "time"
    
func display(ch chan int) {
	time.Sleep(5 * time.Second)
	fmt.Println("Inside display()")
	ch <- 1234
}

func main() {
	ch := make(chan int) 
	go display(ch)
	x := <-ch
	fmt.Println("Inside main()")
	fmt.Println("Printing x in main() after taking from channel:",x)
}

Çıktı olacak

Inside display()
Inside main()
Printing x in main() after taking from channel: 1234

Burada x := <-ch'ye ulaşıldığında main() kanalı kanaldaki veriyi bekleyecektir. Display()'in 5 saniye beklemesi vardır ve ardından veriyi kanal kanalına aktarır. Kanaldan veri alındığında main()'in engeli kaldırılır ve çalıştırılmaya devam edilir.

Kanala veri gönderen gönderici, kanalı kapatarak alıcılara kanala artık veri eklenmeyeceği bilgisini verebilir. Bu esas olarak verileri bir kanala göndermek için bir döngü kullandığınızda kullanılır. Bir kanal kullanılarak kapatılabilir

close(channel_name)

Alıcı tarafında ise kanaldan veri alınırken ek bir değişken kullanılarak kanalın kapalı olup olmadığı kontrol edilebilmektedir.

variable_name, status := <- channel_variable

Durum True ise kanaldan veri aldığınız anlamına gelir. Yanlışsa kapalı bir kanaldan okumaya çalıştığınız anlamına gelir

Goroutinler arasındaki iletişim için kanalları da kullanabilirsiniz. 2 goroutin kullanmanız gerekir; biri verileri kanala iter, diğeri ise verileri kanaldan alır. Aşağıdaki programa bakın

package main
import "fmt"
import "time"

//This subroutine pushes numbers 0 to 9 to the channel and closes the channel
func add_to_channel(ch chan int) {	
	fmt.Println("Send data")
	for i:=0; i<10; i++ {
		ch <- i //pushing data to channel
	}
	close(ch) //closing the channel

}

//This subroutine fetches data from the channel and prints it.
func fetch_from_channel(ch chan int) {
	fmt.Println("Read data")
	for {
		//fetch data from channel
x, flag := <- ch

		//flag is true if data is received from the channel
//flag is false when the channel is closed
if flag == true {
			fmt.Println(x)
		}else{
			fmt.Println("Empty channel")
			break	
		}	
	}
}

func main() {
	//creating a channel variable to transport integer values
	ch := make(chan int)

	//invoking the subroutines to add and fetch from the channel
	//These routines execute simultaneously
	go add_to_channel(ch)
	go fetch_from_channel(ch)

	//delay is to prevent the exiting of main() before goroutines finish
	time.Sleep(5 * time.Second)
	fmt.Println("Inside main()")
}

Burada 2 alt rutin var, biri kanala veri gönderiyor ve diğeri kanala veri yazdırıyor. add_to_channel fonksiyonu 0'dan 9'a kadar olan sayıları toplar ve kanalı kapatır. Aynı anda fetch_from_channel fonksiyonu

x, flag := <- ch ve veriler kullanılabilir hale geldiğinde verileri yazdırır. Bayrak yanlış olduğunda çıkar, bu da kanalın kapalı olduğu anlamına gelir.

Main() içindeki bekleme, goroutinler yürütmeyi bitirinceye kadar main() öğesinden çıkmayı önlemek için verilir.

Kodu yürütün ve çıktıyı şu şekilde görün:

Read data
Send data
0
1
2
3
4
5
6
7
8
9
Empty channel
Inside main()

Seç

Select, kanallar üzerinde çalışan bir switch ifadesi olarak görülebilir. Burada durum ifadeleri bir kanal işlemi olacaktır. Genellikle her vaka ifadesi kanaldan okunma girişiminde bulunulacaktır. Vakalardan herhangi biri hazır olduğunda (kanal okunur), o vakayla ilişkili ifade yürütülür. Birden fazla vaka hazırsa rastgele birini seçecektir. Vakalardan hiçbiri hazır değilse yürütülen bir varsayılan vakanız olabilir.

Aşağıdaki kodu görelim

package main
import "fmt"
import "time"

//push data to channel with a 4 second delay
func data1(ch chan string) {  
    time.Sleep(4 * time.Second)
    ch <- "from data1()"
}

//push data to channel with a 2 second delay
func data2(ch chan string) {  
    time.Sleep(2 * time.Second)
    ch <- "from data2()"
}

func main() {
    //creating channel variables for transporting string values
    chan1 := make(chan string)
    chan2 := make(chan string)
    
    //invoking the subroutines with channel variables
    go data1(chan1)
    go data2(chan2)
    
    //Both case statements wait for data in the chan1 or chan2.
    //chan2 gets data first since the delay is only 2 sec in data2().
    //So the second case will execute and exits the select block
    select {
    case x := <-chan1:
        fmt.Println(x)
    case y := <-chan2:
        fmt.Println(y)
    }
}

Yukarıdaki programın çalıştırılması çıktıyı verecektir:

from data2()

Burada select deyimi verilerin herhangi bir kanalda mevcut olmasını bekler. data2(), 2 saniyelik bir uykudan sonra kanala veri ekler, bu da ikinci durumun yürütülmesine neden olur.

Aynı programdaki seçime varsayılan bir durum ekleyin ve çıktıyı görün. Burada, seçme bloğuna ulaşıldığında, eğer kanalda hazır veri yoksa, verinin herhangi bir kanalda mevcut olmasını beklemeden varsayılan bloğu çalıştıracaktır.

package main
import "fmt"
import "time"

//push data to channel with a 4 second delay
func data1(ch chan string) {  
    time.Sleep(4 * time.Second)
    ch <- "from data1()"
}

//push data to channel with a 2 second delay
func data2(ch chan string) {  
    time.Sleep(2 * time.Second)
    ch <- "from data2()"
}

func main() {
    //creating channel variables for transporting string values  
    chan1 := make(chan string)
    chan2 := make(chan string)
    
    //invoking the subroutines with channel variables
    go data1(chan1)
    go data2(chan2)

    //Both case statements check for data in chan1 or chan2.
    //But data is not available (both routines have a delay of 2 and 4 sec)
    //So the default block will be executed without waiting for data in channels.
    select {
    case x := <-chan1:
        fmt.Println(x)
    case y := <-chan2:
        fmt.Println(y)
    default:
    	fmt.Println("Default case executed")
    }
}

Bu program çıktıyı verecektir:

Default case executed			

Bunun nedeni, seçim bloğuna ulaşıldığında hiçbir kanalın okunacak veriye sahip olmamasıdır. Yani varsayılan durum yürütülür.

Karşılıklı dışlama

Mutex, karşılıklı dışlamanın kısaltılmış halidir. Mutex, bir kaynağa aynı anda birden fazla alt rutin tarafından erişilmesine izin vermek istemediğinizde kullanılır. Mutex'in 2 yöntemi vardır – Kilit ve Kilidi Aç. Mutex, senkronizasyon paketinde bulunur. Bu nedenle, senkronizasyon paketini içe aktarmanız gerekir. Karşılıklı olarak özel olarak yürütülmesi gereken ifadeler mutex.Lock() ve mutex.Unlock() içine yerleştirilebilir.

Bir döngünün kaç kez yürütüldüğünü sayan bir örnekle mutex'i öğrenelim. Bu programda rutinin döngüyü 10 kez çalıştırmasını bekliyoruz ve sayım toplamda saklanıyor. Bu rutini 3 kez çağırırsınız, böylece toplam sayı 30 olur. Sayım, genel bir değişken sayımında saklanır.

Öncelikle programı mutex olmadan çalıştırıyorsunuz.

package main
import "fmt"
import "time"
import "strconv"
import "math/rand"
//declare count variable, which is accessed by all the routine instances
var count = 0

//copies count to temp, do some processing(increment) and store back to count
//random delay is added between reading and writing of count variable
func process(n int) {
	//loop incrementing the count by 10
	for i := 0; i < 10; i++ {
		time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
		temp := count
		temp++
		time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
		count = temp
	}
	fmt.Println("Count after i="+strconv.Itoa(n)+" Count:", strconv.Itoa(count))
}

func main() {
	//loop calling the process() 3 times
	for i := 1; i < 4; i++ {
		go process(i)
	}

	//delay to wait for the routines to complete
	time.Sleep(25 * time.Second)
	fmt.Println("Final Count:", count)
}

sonucu gör

 Count after i=1 Count: 11
Count after i=3 Count: 12
Count after i=2 Count: 13
Final Count: 13

Uyguladığınızda sonuç farklı olabilir ancak nihai sonuç 30 olmayacaktır.

Burada olan şey şu; 3 goroutin, sayım değişkeninde saklanan döngü sayısını artırmaya çalışıyor. Bir anda sayımın 5 olduğunu ve goroutine1'in sayımı 6'ya çıkaracağını varsayalım. Ana adımlar şunları içerir:

Sayımı temp'e kopyala

Sıcaklık artışı

Sıcaklığı saymak için geri depolayın

Goroutine3 ile 1. adımı gerçekleştirdikten hemen sonra olduğunu varsayalım; başka bir goroutine eski bir değere sahip olabilir, örneğin 3 yukarıdaki adımları yapar ve 4'ü geri saklar, bu yanlıştır. Bu, bir rutin zaten değişkeni kullanırken diğer rutinlerin beklemesine neden olan muteks kullanılarak önlenebilir.

Şimdi programı mutex ile çalıştıracaksınız. Burada yukarıda belirtilen 3 adım bir mutekste yürütülür.

package main
import "fmt"
import "time"
import "sync"
import "strconv"
import "math/rand"

//declare a mutex instance
var mu sync.Mutex

//declare count variable, which is accessed by all the routine instances
var count = 0

//copies count to temp, do some processing(increment) and store back to count
//random delay is added between reading and writing of count variable
func process(n int) {
	//loop incrementing the count by 10
	for i := 0; i < 10; i++ {
		time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
		//lock starts here
		mu.Lock()
		temp := count
		temp++
		time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
		count = temp
		//lock ends here
		mu.Unlock()
	}
	fmt.Println("Count after i="+strconv.Itoa(n)+" Count:", strconv.Itoa(count))
}

func main() {
	//loop calling the process() 3 times
	for i := 1; i < 4; i++ {
		go process(i)
	}

	//delay to wait for the routines to complete
	time.Sleep(25 * time.Second)
	fmt.Println("Final Count:", count)
}

Şimdi çıktı olacak

 Count after i=3 Count: 21
Count after i=2 Count: 28
Count after i=1 Count: 30
Final Count: 30

Burada nihai çıktı olarak beklenen sonucu elde ederiz. Çünkü sayımın okunması, arttırılması ve geri yazılması ifadeleri bir mutekste yürütülür.

Hata işleme

Hatalar, açılmamış bir dosyayı kapatmak, var olmayan bir dosyayı açmak vb. gibi anormal durumlardır. İşlevler genellikle hataları son dönüş değeri olarak döndürür.

Aşağıdaki örnek hata hakkında daha fazla bilgi vermektedir.

package main
import "fmt"
import "os"

//function accepts a filename and tries to open it.
func fileopen(name string) {
    f, er := os.Open(name)

    //er will be nil if the file exists else it returns an error object  
    if er != nil {
        fmt.Println(er)
        return
    }else{
    	fmt.Println("file opened", f.Name())
    }
}

func main() {  
    fileopen("invalid.txt")
}

çıkış olacaktır:

open /invalid.txt: no such file or directory

Burada var olmayan bir dosyayı açmaya çalıştık ve er değişkenine hatayı döndürdü. Dosya geçerliyse hata null olur

Özel hatalar

Bu özelliği kullanarak özel hatalar oluşturabilirsiniz. Bu, hata paketinin New() işlevi kullanılarak yapılır. Özel hatalardan yararlanmak için yukarıdaki programı yeniden yazacağız.

Aşağıdaki programı çalıştırın

package main
import "fmt"
import "os"
import "errors"

//function accepts a filename and tries to open it.
func fileopen(name string) (string, error) {
    f, er := os.Open(name)

    //er will be nil if the file exists else it returns an error object  
    if er != nil {
        //created a new error object and returns it  
        return "", errors.New("Custom error message: File name is wrong")
    }else{
    	return f.Name(),nil
    }
}

func main() {  
    //receives custom error or nil after trying to open the file
    filename, error := fileopen("invalid.txt")
    if error != nil {
        fmt.Println(error)
    }else{
    	fmt.Println("file opened", filename)
    }  
}

çıkış olacaktır:

Custom error message:File name is wrong

Burada alan() bir karenin alanını döndürür. Giriş 1'den küçükse, field() bir hata mesajı döndürür.

Dosyaları okuma

Dosyalar veri depolamak için kullanılır. Go, dosyalardan veri okumamızı sağlar

Öncelikle mevcut dizininizde aşağıdaki içeriğe sahip bir data.txt dosyası oluşturun.

Line one
Line two
Line three

Şimdi tüm dosyanın içeriğini çıktı olarak yazdırdığını görmek için aşağıdaki programı çalıştırın.

package main
import "fmt"
import "io/ioutil"

func main() {  
    data, err := ioutil.ReadFile("data.txt")
    if err != nil {
        fmt.Println("File reading error", err)
        return
    }
    fmt.Println("Contents of file:", string(data))
}

Burada veriler, err := ioutil.ReadFile(“data.txt”) verileri okur ve bir bayt dizisi döndürür. Yazdırma sırasında string formatına dönüştürülür.

Dosya yazma

Bunu bir programla göreceksiniz

package main
import "fmt"
import "os"

func main() {  
    f, err := os.Create("file1.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    l, err := f.WriteString("Write Line one")
    if err != nil {
        fmt.Println(err)
        f.Close()
        return
    }
    fmt.Println(l, "bytes written")
    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
}

Burada bir dosya oluşturulur: test.txt. Dosya zaten mevcutsa, dosyanın içeriği kesilir. Writeline() içeriği dosyaya yazmak için kullanılır. Bundan sonra dosyayı Close() kullanarak kapattınız.

Hile Sayfası

Bu Go eğitiminde şunları ele aldık:

konu Açıklama Sözdizimi
Temel tipler Sayısal, dize, bool
Değişkenler Değişkenlere değer bildirme ve atama var değişken_adı türü
var değişken_adı türü = değer
var değişken_adı1, değişken_adı2 = değer1, değer2
değişken_adı := değer
Sabitler Atandıktan sonra değeri değiştirilemeyen değişkenler sabit değişken = değer
Döngü için İfadeleri bir döngüde yürütün. başlatma_ifadesi için; değerlendirme_ifadesi; yineleme_ifadesi{
// bir veya daha fazla ifade
}
Aksi halde Bu bir koşullu ifadedir eğer koşul{
// ifadeler_1
Else {}
// ifadeler_2
}
anahtar Birden fazla durum içeren koşullu ifade ifadeyi değiştir {
vaka değeri_1:
ifadeler_1
vaka değeri_2:
ifadeler_2
durum değeri_n:
ifadeler_n
Varsayılan:
ifadeler_default
}
Dizi Aynı türdeki öğelerin sabit boyutlu adlandırılmış dizisi diziadı := [boyut] tür {value_0,value_1,…,value_size-1}
Dilim Bir dizinin bölümü veya bölümü var dilim_adı [] tür = dizi_adı[başlangıç:bitiş]
fonksiyonlar Belirli bir görevi gerçekleştiren ifade bloğu func işlev_adı(parametre_1 türü, parametre_n türü) return_type {
//ifadeler
}
Paketler Kodu düzenlemek için kullanılır. Kodun okunabilirliğini ve yeniden kullanılabilirliğini artırır paket_namını içe aktar
ertele İçeren işlev yürütmeyi bitirinceye kadar bir işlevin yürütülmesini erteler erteleme işlev_adı(parametre_listesi)
İşaretçiler Başka bir değişkenin hafıza adresini saklar. var değişken_adı *tür
Structure Kendisi aynı veya farklı türde bir öğe daha içeren kullanıcı tanımlı veri türü yapı adı yazın yapı {
değişken_1 değişken_1_tipi
değişken_2 değişken_2_tipi
değişken_n değişken_n_tipi
}
Yöntemler Yöntem, alıcı argümanına sahip bir işlevdir func (değişken değişken türü) methodName(parameter_list) {
}
gorutin Diğer işlevlerle eş zamanlı çalışabilen bir işlev. git işlev_adı(parametre_listesi)
Telegram Kanal Fonksiyonların birbirleriyle iletişim kurma yolu. Bir rutinin verileri yerleştirdiği ve başka bir rutin tarafından erişildiği bir ortam. Bildirmek:
ch := make(chan int)
Kanala veri gönder:
kanal_değişkeni <- değişken_adı
Kanaldan alın:
değişken_adı := <- kanal_değişkeni
Seç Kanallarda çalışan Switch ifadesi. Vaka ifadeleri bir kanal işlemi olacaktır. Kanallardan herhangi biri veriyle hazır olduğunda bu durumla ilgili ifade yürütülür. seçme {
durum x := <-kanal1:
fmt.Println(x)
durum y := <-kanal2:
fmt.Println(y)
}
Karşılıklı dışlama Mutex, bir kaynağa aynı anda birden fazla alt program tarafından erişilmesine izin vermek istemediğinizde kullanılır. Mutex'in 2 yöntemi vardır – Kilitle ve Kilidini Aç mutex.Lock()
//ifadeler
mutex.Unlock().
Dosyaları oku Verileri okur ve bir bayt dizisi döndürür. Veri, hata := ioutil.ReadFile(dosya adı)
Dosya yaz Verileri bir dosyaya yazar l, hata := f.WriteString(text_to_write)