İçeriğe geç

Veri Türleri

saQut’taki her veri parçasının bir türü (type) vardır. Tür, bir değişkenin hangi tür değerleri tutabileceğini ve o değer üzerinde hangi işlemleri yapabileceğinizi belirler.

Bu türler değerlerini doğrudan taşır. Birini diğerine atadığınızda değer kopyalanır; böylece iki değişken birbirinden bağımsız hale gelir.

32 bitlik işaretli tam sayı.

int a = 42;
int b = -100;
int c = 0xFF; // onaltılık, 255
int d = 0b1010; // ikilik, 10
int e = 0777; // sekizlik, 511

Aralık: -2.147.483.648 ile 2.147.483.647. Taşma, tanımlı iki’nin tümleyeni (two’s-complement) davranışıyla sarar (hata fırlatmaz). Daha geniş bir tam sayıya ihtiyacınız varsa longint kullanın.

64 bitlik işaretli tam sayı. int sınırına sığmayan değerler için (dosya boyutları, offset’ler, hash’ler, zaman damgaları).

longint big = 9223372036854775807; // int64 azami
longint scaled = big + 1; // -9223372036854775808'e sarar
int small = 42;
longint widened = small; // int'ten longint'e kayıpsız, serbest

Aralık: -9.223.372.036.854.775.808 ile 9.223.372.036.854.775.807.

longint, sayısal dönüşüm kulesinin dışında durur (bilinçli tercih). int değerini longint’e genişletmek kayıpsızdır ve örtük yapılır. Tersi (longint’ten int’e) ve longint’i float, double veya decimal ile karıştırmak açık bir as dönüşümü ister; çünkü bu dönüşümler veri kaybına yol açabilir ve saQut bunları sessizce yapmaz.

32 bitlik IEEE 754 tek hassasiyetli (single precision) sayı. Yaklaşık 7 anlamlı ondalık hane taşır, bu yüzden sonuçlar tek hassasiyet yuvarlamasını gösterir.

float x = 3.14;
float y = 0.5;
float f = 0.1;
print(f + 0.2); // 0.300000012 (tek hassasiyet)

64 bitlik IEEE 754 çift hassasiyetli (double precision) sayı, yaklaşık 15 ila 16 anlamlı hane. 0.2 gibi çıplak bir ondalık literal varsayılan olarak double’dır; yalnızca bir float bağlamında float olur. e veya E ile bilimsel gösterim kullanabilirsiniz.

double d = 0.1;
print(d + 0.2); // 0.3
double z = 1e5; // 100000.0
double w = 2.5e-3; // 0.0025

float ve double gerçek genişliklerinde saklanır, bu yüzden double’dan float’a dönüşüm hassasiyet kaybeder. Bu dönüşüm açık bir as float gerektirir.

true ya da false değerini alan mantıksal bir türdür. Dahili olarak int biçiminde saklanır (true için 1, false için 0).

bool isReady = true;
bool done = false;

0 ile 255 arasında küçük bir işaretsiz tam sayı.

byte b = 100;
byte c = 200;
// byte d = 300; HATA, aralık dışı

byte, aritmetik işlemlerde otomatik olarak int türüne genişletilir (örn. byte + byteint). Geri dönüştürmek için as byte kullanın.

byte a = 200;
byte b = 100;
int sum = a + b; // byte → int genişletme
byte result = sum as byte; // açık geri dönüşüm

saQut, farklı türler arasında açık bir as dönüşümü olmadan örtük (otomatik) dönüşüm yapmaz. Bu, sessizce veri kaybını önler.

İki sayısal tür bir aritmetik işlemde (+, -, *, /, % vb.) kullanıldığında, sonuç türü iki işlenenin daha geniş olanıdır:

int a = 5;
float b = 3.0;
// int + float → float
float result = a + b; // 8.0 (int, float'a genişletildi)

En dardan en genişe sayısal sıralama:

Sıra Tür
0 int
1 float
2 double
3 decimal

Buna göre:

  • int + intint
  • int + floatfloat
  • float + doubledouble
  • byte + byteint (byte önce int’e yükseltilir)

longint bu tabloda yer almaz. Kendi kuralı vardır: longint + int, int’i yükseltir ve longint verir; ama longint, açık bir dönüşüm olmadan float, double veya decimal ile karışmaz.

int a = 5;
float b = 2.0;
int x = a + a; // int + int → int → 10
float y = a + b; // int + float → float → 7.0
float z = b + b; // float+float → float → 4.0

Kural işlenenlere bakar, atama yaptığınız değişkene değil. Bu, akılda tutulması gereken bir tuzak doğurur:

float half = 1 / 2; // → 0.0, 0.5 DEĞİL!

Neden? Hem 1 hem 2 tam sayıdır, bu yüzden 1 / 2 önce tam sayı bölmesi olarak hesaplanır, sıfıra doğru budanır ve 0 verir. Ancak ondan sonra bu 0, float değişken için 0.0’a genişletilir. Hedefi float olarak bildirmek, bölme işleminin nasıl yapılacağını değiştirmez.

0.5 elde etmek için işlenenlerden en az birini float yapın ki tüm işlem float olarak gerçekleşsin:

float ok = 1.0 / 2; // → 0.5 (bir float işlenen diğerini de yükseltir)

Tam sayı bölmesi her zaman budar (kesirli kısmı atar):

print(10 / 3); // 3 (3.333 değil)
print(1 / 2); // 0
print(7 % 3); // 1 (modül, kalan)

Daha geniş bir türü, açık bir dönüşüm olmadan daha dar bir türe atayamazsınız:

int a = 1.5; // HATA, float sabit int'e atanamaz (E003)
float b = 42; // GEÇERLİ, int sabit float bağlamında
int c = b; // HATA, float'tan int'e 'as' gerekir
int d = b as int; // GEÇERLİ, açık dönüşüm (budar)

Tam sayı sabitleri, beklendiği bağlama uyum sağlar:

float x = 1; // GEÇERLİ, 1 sabiti float bağlamında 1.0 olur

Ancak ondalıklı sabitler asla sessizce tam sayıya dönüşmez:

int y = 1.5; // HATA, float sabit int bağlamında (E003)

Bu türler veriye bir referans tutar. Birini diğerine atadığınızda, iki değişken de aynı alt değeri paylaşır. Birini değiştirmek diğerini de etkiler.

UTF-8 karakterlerinden oluşan değişmez (immutable) bir dizidir.

string s = "Merhaba, saQut!";
string empty = "";

string anlamsal olarak bir değer türüdür (yazarken kopyalama, copy-on-write), ancak çalışma zamanında bir referans türüdür. Metinler hakkında daha fazlası…

Birden çok değeri tek bir isim altında toplayan özel bir bileşik türdür.

struct Point {
int x;
int y;
}
Point p;
p.x = 10;
p.y = 20;

Yapılar hakkında daha fazlası…

Aynı türden değerlerin sabit uzunluklu bir dizisidir.

int[] numbers = [1, 2, 3, 4, 5];
string[] names = ["ali", "veli", "deli"];

Diziler hakkında daha fazlası…

Herhangi bir tür, sonuna ? eklenerek nullable yapılabilir. Nullable bir değişken normal değerlerinin yanı sıra null da tutabilir.

int? maybeNumber = 42;
maybeNumber = null; // GEÇERLİ, nullable
int normalNumber = 42;
// normalNumber = null; HATA, int null tutamaz

Nullable türler derleme zamanında denetlenir. Nullable bir değeri, önce null olmadığını kontrol etmeden kullanamazsınız:

int? x = getValue();
// print(x); HATA, x null olabilir
if (x != null) {
print(x); // GEÇERLİ, null değil'e daraltıldı
}

Güvenli dönüşüm için as işlecini kullanın. Dönüşüm başarısız olursa, hedef nullable olduğunda null döner:

string s = "42";
int? n = s as int?; // 42
if (n != null) { /* n'yi kullan */ }

enum, adlandırılmış sabitler kümesi tanımlar.

enum Color { Red, Green, Blue }
void main() {
Color c = Color.Green;
print(c); // 1 çıktısı verir (indis)
}

Enum’lar switch ile çalışır:

switch (c) {
case Color.Red: print(0);
case Color.Green: print(1);
case Color.Blue: print(2);
}
Tür Kategori Atama Varsayılan
int Temel Kopya 0
float Temel Kopya 0.0
bool Temel Kopya false
byte Temel Kopya 0
string Birleşik Referans ""
struct Birleşik Referans Sıfır alanlar
Type[] Birleşik Referans null
Type? Nullable Referans null
  • Değişkenleri nasıl oluşturacağınızı ve kullanacağınızı öğrenin
  • İşleçlerin farklı türlerle nasıl çalıştığını görün