Verilənlərin tipləri, dəyişənlər və sabitlər. (Golang)

Bu məqalədə biz Golang-də sadə verilənlərinin tiplərinə nəzər salacaq, dəyişən və sabitlərin necə təyin olunduğunu öyrənəcəyik.

Elnur Mammadli
7 min readNov 21, 2022

Dəyişən nədir?

Dəyişənlər proqramlaşdırmadakı ən vacib konseptlərdən biridir. Yazdığımız proqram təminatlarında çox zaman müəyyən bir dəyərin müvəqqəti yaddaşda saxlanılmasına və həmin dəyərin proqram daxilində istifadəsinə ehtiyac duyulur. Bu zaman həmin dəyərin yaddaşdakı ünvanını adlandırmaq gərəklidir. Dəyişən informasiya üçün simvolik bir addır. Biz bu ad vasitəsilə dəyişənin kompüter yaddaşındakı ünvanına istinad edərək həmin dəyişəndən proqram daxilində istifadə edirik. Hər bir dəyişənin təməl olaraq aşağıdakı 6 özəlliyi vardır.

  1. Ad

Ad informasiyanın simvolik “başlığıdır”. Çox güman ki, ad proqramçı üçün ən önəmli atributdur, çünki dəyişən həmin ad vasitəsilə əlçatandır. Hər bir dəyişənin mövcud olduğu “əhatə dairəsi”-ndə unikal bir adı olmalıdır.

2. Tip

Tip dəyişənin hansı növ dəyərləri özündə saxlaya biləcəyini göstərir. Proqramlaşdırma dillərini statik və dinamik tipli olmaqla iki növə ayırmaq olar. Statik tipli dillərdə (C, C++, Golang, Java) dəyişənin tipi onu istifadə etməzdən öncə bildirilməlidir. Dinamik tipli dillərdə (Python, JavaScript) isə dəyişənin tipi icra zamanı (run time) təyin olunur.

3. Əhatə dairəsi (Scope)

Yaxşı bir proqram, romanın fəsillərə bölündüyü və fəslin də paraqraflara bölündüyü kimi kiçik hissələrə (funksiyalara) “parçalanmışdır”. Bir funksiya daxilində təyin olunmuş dəyişən bu funksiyanın xaricində əlçatmazdır. Bu da bizə imkan verir ki, biz eyniadlı dəyişəni fərqli məqsədlər üçün istifadə edək. Nümunə olaraq “name dəyişəni bir funksiya daxilində tələbənin, digər bir funksiyada isə şərabın adını göstərə bilər. Hər bir dəyişənin aktiv olduğu təsir dairəsi vardır.

package main

import "fmt"

// getStudentName və getWineName ayrı-ayrı əhatə dairəsidir

func getStudentName() string {
name := "John"
return name
}

func getWineName() string {
name := "Cabernet Franc"
return name
}

func main() {
fmt.Println(getPersonName())
fmt.Println(getWineName())
}

4. Yaşam dövrü (A Life Time)

Bir dəyişənin yaşam dövrü birbaşa onun əhatə dairəsi ilə əlaqələdir. Dəyişənlər onların təyin olduğu sətirdən başlayaraq “həyata gözlərini açar” və proqram onun təyin olunduğu əhatə dairəsindən kənara çıxan kimi “ölər”.

5. Yaddaşdakı ünvanı

Hər bir proqram icra olunan zaman OS tərəfindən həmin proqramın icrasına görə tələb olunan dəyişənlərin saxlanılması üçün yaddaş ayrılır. Hər bir dəyişən yaşam dövründə onun üçün ayrılmış yuvada (slot) mövcud olur.

Verilənlərin tipi

Golang-də dəyişənlərin tipini 4 qrupa bölə bilərik.

Bunlar aşağıdakılardır:

  1. Sadə tiplər (Basic types)
  2. Aqreqat tiplər (array)
  3. İstinad tiplər (struct)
  4. İnterface tiplər

Golang-də verilənlərin sadə tipləri aşağıdakılardır.

Dəyişənlərin susmaya görə dəyərləri (Zero value)

Golang-də digər proqramlaşdırma dillərindən fərqli olaraq dəyişən təyin olunan zaman ona dəyər verilməzsə, onun dəyəri null və ya undefined olmur. Təyin olunan dəyişənin tipinə uyğun ilkin dəyər (zero value) verilir. Bu ilkin dəyərlər yuxarıdakı cədvəldə göstərilmişdir.

Dəyişənlərin elan olunması

Golang-də dəyişənlərin elan olunmasının bir neçə yolu vardır. Ümumi sintaksis aşağıdakı kimidir:

var dəyişəninAdı dataType = ilkinDəyər

ilkinDəyər məcburi deyildir. Əgər ilkin dəyər təyin edilməzsə, onda dəyişənə verilən tipə uyğun zero value mənimsədiləcəkdir.

Aşağıdakı nümunədə biz integer tipində i dəyişənini elan etmişik.

var i int

Gördüyünüz kimi elan etmə zamanı dəyişənə heç bir dəyər verməmişik bu zaman i dəyişəni elan olunduğu tipə uyğun ilkin dəyərə (zero value) sahib olacaqdır. Bizim nümunədə i-nin dəyəri 0 olacaqdır. Bir çox dildən fərqli olaraq Golang-də dəyişənin tipi dəyişənin adından sonra qeyd olunur buna ilk zamanlar uyğunlaşmaq çətin ola bilər. Amma diqqət yetirsəniz, bu yanaşma daha çox ingilis dilinə yaxındır (i is integer).

Golang-də dəyişənin elanı zamanı da dəyər verə bilərik.

var i int = 1

Yuxarıda qeyd olunan hər iki növ dəyişən elan etmə yanaşmasına Golang-də uzun dəyişən elanı (long variable declarations) deyilir.

Biz həmçinin qisa dəyişən elanından da istifadə edə bilərik (short variable declaration).

i := 1

Bu tip dəyişən elanı yalnız lokal çərçivədə (local scope) edilə bilər. Yəni aşağıdakı kod hissəsi emal olunmayacaqdır.

package main

import (
"fmt"
)

i := 1

func main() {
fmt.Println(i)
}

Bu kodu emal etməyə çalışdıqda aşağıdakı xəta ilə qarşılaşacaqsınız.

./prog.go:8:1: syntax error: non-declaration statement outside function body

Golang statik tipli dil olsa da, siz dəyişəni aşağıdakı formada da təyin edə bilərsiniz( type inference). Bu halda Golang uyğun tipi dəyərə əsasən seçəcəkdir.

var i = 1

Siz bir neçə dəyişəni bir sətirdə elan edə bilərsiniz.

var var1, var2, var3 int

Həmçinin ilkin dəyər və qısa dəyişən elanını da bir sətirdə edə bilərsiniz.

var var1, var2, var3 int = 1, 2, 3
var var3, var4, var5 = 1, 2.2, false
var6, var7, var8 := 1, 2.2, false

Bir var bloku vasitəsilə fərqli tiplərdə olan dəyişənləri elan edə bilərsiniz.

var (
var1 = 50
var2 = 25.22
var3 string = “Salam Dünya”
var4 bool
)

Dəyişənlərin adlandırılması qaydaları

Golang dəyişənlərin adlandırılmasında çoxlu qadağalar tələb etmir, amma nəzərə alınmalı bir neçə qayda var ki, onlar aşağıdakılardır:

  • Dəyişənin adı bir sözdən ibarət olmalıdır, arada heç bir boşluq olmamalıdır.
  • Dəyişənlərin adlarında yalnız rəqəm, hərf və _ istifadə edə bilərsiniz.
  • Dəyişənlərin adı rəqəm ilə başlaya bilməz.

Golang case sensitive olduğundan dəyişənlərin adlandırılmasında bir qədər diqqətli olmağınızda fayda var. Nümunə olaraq qeyd edə bilərik ki, userNameUSERNAME ayrı-ayrı dəyişən adlarıdır.

Golang-də tövsiyə olunur ki, dəyişənlərin adı sadə və bir sözdən ibarət olsun, əgər dəyişənin adı iki sözdən ibarətdirsə, bu zaman tövsiyə olunan stil camelCase-dir. Siz altdan xətt də (_) istifadə edə bilərsiniz, amma bu Golangvari (Golang idiomatic) deyildir. Əgər dəyişənin adı böyük hərflə başlarsa, onda bu dəyişən digər paketler tərəfindən də əlçatan olacaqdır.

Tip çevrilməsi

Golang-də iki fərqli tipdə olan dəyişənlər üzərində riyazi əməliyyatlar etmək mümkün deyildir. İlk öncə həmin dəyişənlər eyni tipə çevrilməlidir.

Golang-də tiplərin konvertasiyası çox sadədir. Sadəcə dəyişəni hansı tipə çevirmək istəyirsinizsə, önünə həmin tipi əlavə edərək mörtərizə daxilinə dəyişəni yazmaq kifayətdir.

var1 := 10 // int
var2 := 10.5 // float64

// yanlış
// var3 := var1 + var2

// doğru
var3 := var1 + int(var2) // var3 => 20

Xüsusi tip

Golang-in daxilində bir neçə tip mövcuddur, amma biz istəsək, xüsusi tip də yarada bilərik.

type xüsusiTip mövcudTip

Yuxarıdakı sintaksisdə xüsusiTip mövcudTipdən törədilmişdir. mövcudTipin bütün xüsusiyyətləri xüsusiTipdə də olacaqdır və əlavə olaraq yeni xüsusiyyətlər əlavə edə bilərsiniz. Bu halda xüsusiTip mövcudTipdən olan iki dəyişəni müqayisə edə bilmərik.

package main
import "fmt"
type float float64

func main() {
var f float = 52.2
var g float64 = 52.2 fmt.Println("f == g", f == g)
}

Bu kodu icra etməyə çalışdıqda aşağıdakı error ilə qarşılaşacağıq.

./prog.go:10:29: invalid operation: f == g (mismatched types float and float64)t

Tip təxəllüsü (Type Alias)

Aşağıdakı sintaksisdən istifadə edərək hər hansısa bir mövcud tip üçün təxəllüs (alias) yarada bilərik.

type təxəllüs = mövcudTip

Xüsusi tipdən fərqli olaraq yuxarıdakı halda biz yeni bir tip yaratmırıq, sadəcə olaraq mövcud tip üçün yeni bir ad təyin edirik. Ona görə də aşağıdakı nümunədə biz fg dəyişənlərini bir-biri ilə müqayisə edə bilərik.

package main
import "fmt"

type float = float64

func main() {
var f float = 52.2
var g float64 = 52.2 fmt.Println("f == g", f == g)
}
f == g true

Sabitlər (Constants)

Sabit olaraq təyin olunmuş bir dəyişənin dəyəri proqramın icrası zamanı dəyişdirilə bilməz. Sabit dəyişənin dəyərini dəyişməyə cəhd etdiyinizdə error ilə qarşılaşacaqsınız. Golang-də sabit yaratmaq üçün const açar sözündən istifadə etməlisiniz.

const sabitAdı [tipi] = sabit_dəyər

tip-i qeyd etmək məcburi deyildir Golang dəyərə əsasan müvafiq tipi seçəcəkdir.

const pi = 3.14

Golang-də sabitin dəyəri emal zamanı bilinməlidir. Əgər siz bir sabitə dəyər olaraq hansısa bir funksiyadan qayıdan dəyəri vermək istəsəniz, bu zaman siz error ilə qarşılaşacaqsınız.

package main

import (
"fmt"
"math"
)

func main() {
const a = math.Sqrt(4)
fmt.Println(a)
}
./prog.go:9:12: math.Sqrt(4) (value of type float64) is not constant

Dəyişənlərin təyini zamanı istifadə etdiyimiz yanaşmaları sabitlərə də tətbiq ede bilərik.

const const_1, const_2 = value_1, value_2
const (
const_1 = value_1
const_2 = value_2
)

Bir mötərizə daxilindəki sabitlərə açıq-aşkar dəyər verməmişiksə, dolayı yolla özündən əvəlki sabiti təkrarlaya bilər .

const (
a = 1 // a == 1
b = 2 // b == 2
c // c == 2
d // d == 2
)

iota ifadəsi

Golang sadalanan sabitləri bəyan etmək üçün iota açar sözünü təklif edir. Bu açar söz hər istifadə olunduğu zaman sabitin dəyərini 1 vahid artırır və bu artımı 0-dan başlayaraq edir.

const (
a = iota // a == 0
b = iota // b == 1
c = iota // c == 2
d // d == 3 (dolayısı ilə d = iota)
)

_ (blank identifier) istifadə edərək iota -nın dəyərini boş keçmək olar.

const (
a = iota + 1 // a == 1
_ // (dolayısı ilə _ = iota + 1 )
b // b == 3 (dolayısı ilə b = iota + 1 )
c // c == 4 (dolayısı ilə c = iota + 1 )
)

iota üçün bir neçə nümunə

type Direction int

const (
North Direction = iota
East
South
West
)
const (
Blue int = iota
Green
Indigo
Orange
Red
Violet
Yellow
)

Məsləhət görünən mənbələr:

--

--

Elnur Mammadli

I am Software Developer at PASHA Bank OJSC. I am autodidact.