Upload
mahmut-bulut
View
456
Download
51
Embed Size (px)
DESCRIPTION
Rust programming language introduction book for Turkish developers. It is just the first version, so it will be updated during the development of Rust. Mahmut Bulut ================= Bu kitap Rust programlama diline basit bir giriş olması niteliğinde yazıldı, dilin kul- lanımını arttırmak ve Türk geliştiricilere/kullanıcılara dili tanıtmak amacı güt- mektedir. Rust şu anda prototip seviyesinde olduğundan; keskinleştirilmiş ve yapının iskeletini oluşturan kısımları buraya aldım. Dilin daha üzerinde tartışılan ve gelecek versiyonlarında yer alacak tüm semantik ve sentaks yapısı bu kitabın içeriğinde değildir. Rust’ın derin semantik yapısına ve çekirdek ilkelerine değinerek okuyucu zorlamak istemediğimden basit ve sade, günlük hayatta kullanılabilecek cinsten örnekler vermeye önem verdim. Kitap Rust’a yeni başlayanlar ve ilgi duy- anlar için birebirdir. Ayrıca bu kitap Rust programlama dilinin yazıldığı zamana ait Türkçe dökümantasyonu olma özelliğini de taşır. Türkçe bilişim terminolojisine girmeyen ama yeni tanımlanmış bazı terimleri de Türkçeye kazandırmak amacı da gütmektedir.
Citation preview
Rust’a Giriş
M A H M U T B U L U T
v.1Rust versiyon: 0.4
Telif Hakları
© Her hakkı saklıdır.
Normal ve kanunî iktibaslarda kaynak gösterilmesi zorunludur.
i
Mahmut BULUT, Eskişehir Osmangazi Üniversitesi Bilgisayar Mühendisliği bölümünde öğrenimini sürdürmektedir. Yapay zeka ve topluluk zekası konusunda çalışmalar yapmaktadır, Haskell’in Hackage veritabanında Planlama ve MAS sistem desteği üzerinde çalışmaktadır. Mageia Linux dağıtımının QA sorum-lusudur. 2012 yılı itibariyle Rust programlama dilinin oluşturulmasında rol almıştır ve ana geliştiricilerinden biridir. Özel bir şirkette çalışmasına devam etmekte ve Rust programlama dilini de geliştirmektedir.
ii
Önsöz
Bu kitap Rust programlama diline basit bir giriş olması niteliğinde yazıldı, dilin kul-lanımını arttırmak ve Türk geliştiricilere/kullanıcılara dili tanıtmak amacı güt-mektedir. Rust şu anda prototip seviyesinde olduğundan; keskinleştirilmiş ve yapının iskeletini oluşturan kısımları buraya aldım. Dilin daha üzerinde tartışılan ve gelecek versiyonlarında yer alacak tüm semantik ve sentaks yapısı bu kitabın içeriğinde değildir. Rust’ın derin semantik yapısına ve çekirdek ilkelerine değinerek okuyucu zorlamak istemediğimden basit ve sade, günlük hayatta kullanılabilecek cinsten örnekler vermeye önem verdim. Kitap Rust’a yeni başlayanlar ve ilgi duy-anlar için birebirdir. Ayrıca bu kitap Rust programlama dilinin yazıldığı zamana ait Türkçe dökümantasyonu olma özelliğini de taşır. Türkçe bilişim terminolojisine girmeyen ama yeni tanımlanmış bazı terimleri de Türkçeye kazandırmak amacı da gütmektedir.
iii
İthaf
Anneme...
iv
İçindekiler1- Rust’a Genel Bakış 6 1.1- Kitap Konvansiyonları 6 1.2- Nedenler ve Amaçlar 6 1.3- Özellikler 62- Rust’ın Temelleri 8 2.1- Kurulum 8 2.1.1- Parçalar ve İnşaa Sistemi Önbilgisi 8 2.1.2- İşletim Sistemine Kurulum 8 2.1.3- Editör ve Geliştirme Ortamları 10 2.2- İlk Adımlar 10 2.3- Değişkenler 11 2.3.1- Immutable(Değişmez) Değişkenler 11 2.3.2- Mutable(Değişen) Değişkenler 12 2.3.3- Tip Tanımlamaları 12 2.3.4- İfade Yapısı/Sentaks 13 2.4- Veri Tipleri 17 2.4.1- Literaller 19 2.4.2- Sabitler 19 2.4.3- Operatörler 19 2.4.4- Sentaks Genişletmeleri 20
3- Program Akışı 21 3.1- Kontrol Yapıları 21 3.1.1- Koşullu Yapılar 21 3.1.2- Örnek Eşleme 22 3.1.3- Döngüler 23 3.2- Veri Yapıları 24 3.2.1- Struct 24 3.2.2- Enumeration 25 3.2.3- Tuple 26
v
B Ö L Ü M 1
Rust’a Genel Bakış
Kitap KonvansiyonlarıBu kitapta mümkün olduğunca basit ve anlaşılır bir konvansiyon kullanmak iste-
dim. Bundan dolayı sadece kodlar, uyarılar ve örnekler yer alacak.
Kodların ve komutların yazım stili ise ”bu şekilde” olacaktır.
Uyarıların yazım stili italik olacak şekildedir. Örnekler ve kod parçacıkları(snip-pets) yine kod konvansiyonu şeklinde yazılacaktır.
Nedenler ve AmaçlarŞuana kadar geliştirilen hiçbir programlama dili bize tam manalı paralelizm,
statik tip tanımlamasında kesinlik, hafıza yönetiminde ve performansta güçlülük sağlamadı. Bunu yapan diller çok az olduğu gibi ata olan C bize tip tanımlama-larında zorluk ve hafıza yönetiminde güç kaybı yaşattı. Günümüzde meşhur olan scripting dillerine rağmen derlenebilir ve her ortamda çalışabilmesi öngörülen diğer derlenebilir dillerden farklı, komplex akışların uygulanabildiği dillere ihtiyaç duyuldu. Bu dillere örnek olarak Haskell ve OCaml verilebilir fakat bu diller alt-seviye dillerle aralarında soyut bir ayrım olduğu için düşük seviyeye yakın program yazımını zorlaştırıyordu. Bu zorluğu çözebilmek adına C ve C++’ın özelliklerin-den de alınması ve harmanlanması gerekiyordu. Mozilla Arge’si tüm bunların so-nucunda bütün iyi özellikleri alan bir programlama dili olan Rust’ı ortaya çıkardı.
ÖzelliklerRust esnektir. En belirgin özelliklerinden biri de bu özelliğidir. Esnekliğin sebebi
tip tanımlamalarının zorunlu olmamasıdır. Tipleri keskinleştirip yumuşatmak ve birbirlerine çevrimini sağlamak sizin elinizdedir. Belirtilen her tip tanımlaması ke-
6
skin tipi oluşturup dönüşümünü zor hale getirirken, belirtilmeyen tipler aynı isimli başka değişkenlerin oluşumuna engel olmaktadır. Bu iyi birşeydir ve aynı ada sahip iki tane farklı değişken oluşturabilmenize olanak sağlar.
Rust aynı zamanda paralelizme önem verir, mesaj aktarımı yoluyla paralel çalışmayı destekler bu hafif ve işlemci yormayan bir sistemdir. Diğer bellek pay-laşımlı çalışan sistemlere nazaran daha iyi bir performansı da beraberinde getirir.
Başta da belirttiğimiz gibi yüksek seviyeli programlama dillerinden örnek alınan kompleks sistem dizaynına olanak sağlayan dereceli fonksiyon tanımlama-larına izin verir. Bu Haskell ve Ocaml’ın da bir özelliğidir.
C’deki struct, enum ve typedef kalıplarını daha da güçlendirerek sunar.
Rust birçok programlama dilinin uygulama biçimlerini de kendine dahil et-miştir, örnek olarak:
• Go programlama dilinden yığın büyüme algoritması
• SML’in veri yapıları
• C#‘ın makine kodu oluşturma ve birleştirme sekansı
• C++’ın hafıza referanslama ve destructor özelliği
• Cyclone ve ML Kit’in hafıza belirleme ve sızıntı önleme sistemleri
• Haskell’in tip sınıfları ve dönüşüm sistemleri
• Python’ın lexer sistemi
• Ruby’nin blok sentaksı (parantezlemesiz sistem)
Rust tamamıyla orijinal bir dil değildir bunun nedeni tüm dillerin en güçlü özel-liklerini alarak arındırılmış sentaksı ile tüm işleri başarabilen bir sisteme evrilme amacında olmasıdır. Rust gelecek senelerde en güçlü ve en kolay programlama dili olma, sistem kontrolü, paralelizm ve hata toleranslı sistemlerin çekirdeğinde rol ala-cak bir aracı olma misyonunu yüklenerek en iyi yere gelmeyi planlamaktadır.
7
B Ö L Ü M 2
Rust’ın Temelleri
KurulumParçalar ve İnşaa Sistemi Önbilgisi
Kurulum üç çalıştırılabilir ve kütüphanelerden oluşmaktadır. Bunlar:
• rustc (Rust Derleyicisi)
• rustdoc (Rust Dokümantasyon Oluşturucu)
• cargo (Rust Paket Yöneticisi)
• librustllvm, librustrt, libcore, libstd, librustc, libsyntax ve libmorestack kütüphaneleri (sistem oluşturulurken kullanılan diğer kütüphaneler önceden yazılmış açık kaynak kütüphanelerdir)
İnşaa sistemi 3 fazdan oluşmaktadır her bir derleyici fazı kendinden sonraki der-leyici fazını yapacak şekilde düzenlenmiştir. Faz.3 derleyicisi son derleyiciyi yaptığında(kendini) Faz.2 ile birebir aynı bir imaj oluşturur(kendini yapan ile). Bütün bu işlemlere ön-ayak olan ise bir önceki rust derleyicisi versiyonun son der-leyicisidir. Bu derleyici yeni sistemin Faz.0‘ıdır.
İşletim Sistemine Kurulum•Windows
Eğer Windows kullanıyorsanız sisteminize sırasıyla
• MinGW ve MSYS paketi (versiyon numarası 20110802 olmak üzere)
• MsysGit (Kurduktan sonra MinGW kurulum dizinindeki .bashrc dosy-asına aşağıdaki satırı ekleyin
8
export PATH=$PATH:/c/Program\ Files/Git/bin
ve kaydedin.
• libpthread kütüphanesini kurun versiyon numarası 2.8.0-3 (libpthread-2.8.0-3-mingw32-dll-2.tar.lzma)
tüm bu yazılımları sisteminize kurduktan sonra http://www.rust-lang.org/ ad-resindeki yükleyici’yi indirmelisiniz. Bu paket hazır derlenmiş ve kullanıma hazır win32 çalıştırılabilirlerini ve kütüphanelerini içermektedir. Kurulum sırasında PATH ortam değişkenine Rust’ı ekle seçeneğinin işaretli olduğundan emin olun.
Kurulum tamamlandığında artık Rust’ı kullanabilir durumda olacaksınız.
•*NIX türevleri ve LinuxEğer *NIX türevi (buna MacOS’da dahil olmak üzere) veya Linux dağıtımların-
dan birini kullanıyorsanız
• g++ 4.4 veya clang++ 3.x serisi
• python 2.6 veya sonraki bir sürüm (fakat 3.x serisi olmamak kaydı ile)
• perl 5.0 veya daha sonraki bir sürüm
• gnu make 3.81 veya daha sonraki bir sürüm
• curl
yazılımlarının sisteminizde yüklü olduğundan emin olun. Tüm bu gereksinimler-den emin olduktan sonra Rust’ı derlemek şu şekildedir:
$ wget http://dl.rust-lang.org/dist/rust-0.4.tar.gz
$ tar -xzf rust-0.4.tar.gz
$ cd rust-0.4
$ ./configure
$ make && make install
Benim yazdığım zamanda Rust derleyicisinin versiyonu 0.4’tü, şimdi yenilenmiş olabilir güncel kaynak kodu yine Rust’ın kendi sitesinde bulabilirsiniz.
9
Editör ve Geliştirme OrtamlarıRust kodu yazabilmek için çeşitli editörler ve destekler mevcuttur. Bunlara ör-
nek vermek gerekirse Eclipse geliştirme ortamı, TextMate editörü, Vim ve Emacs editörleri verilebilir.
• TextMate için destek paketi: Rust.tmbundle
• Eclipse plugin desteği: Oxide
• Emacs ve Vim için destek ise rust’ın kendi kaynak kodunda src/etc dizini altında bulunmaktadır.
• Sublime Text 2 için Sublime Package Manager yoluyla Rust desteği yüklene-bilir.
• KDE’nin editörü Kate için ise yine kaynak kodun src/etc/kate dizini altında desteğini bulabilirsiniz.
Rust daha çok yeni bir dil olduğundan dolayı tam anlamıyla bağımsız bir IDE geliştirilmedi. Şimdilik elimizdeki editör ve destek miktarının bu kadar olduğunu belirtmekle yetinelim. Geliştirmeler oldukça kitabın yeni revizyonlarında bunları belirteceğim.
İlk AdımlarRust genel olarak veri yapılarında C’den farklı değildir, tiplerin tamamı C’nin
birebir kopyasıdır fakat bazı tipler üzerinde fazlaca çalışılmış ayrıca başka tiplerde ekleme yapılmıştır, Rust’ı anlatırken çoğu zaman C ile karşılaştıracağız. Rust pro-gramları .rs dosya uzantısını kullanırlar, .rc uzantısı ise Crate denilen bağımsız derleme birimlerinin özelliklerini belirten dosyalardır. Şimdilik bunlara değinme-den sadece bir dosyadan oluşan çalıştırılabilirleri anlatacağız.
İlk programımız klasik bir Merhaba Dünya olup helloworld.rs isimli bir dosya açarak:
fn main() {
io::println("Merhaba Dünya! Rust’a hoşgeldin!");
}
10
metnini kaydediyoruz. Rust derleyicisini sisteminize başarı ile yüklediyseniz
rustc helloworld.rs
komutunu verdiğinizde size eğer *nix sistem üzerinde iseniz helloworld isimli bir çalıştırılabilir oluşturulacaktır(eğer windows üzerinde iseniz bu çalıştırılabilirin adı helloworld.exe olur). Çalıştırdığınızda ise
Merhaba Dünya! Rust’a hoşgeldin!
çıktısını alırsınız. Rust eğer çalıştırılabilir oluşturulacaksa C’deki gibi bir main fonksiyonuna ihtiyaç duyar, aynı zamanda eğer kütüphanelerinde bulunmayan bir fonksiyonla karşılaşırsa hata mesajını en dar şekilde vererek deterministik bir hata çıktısı verir. Şimdi kodumuzu biraz değiştirerek şu hale getirelim
fn main() {
io::bu_satırı_bas("Merhaba Dünya! Rust’a hoşgeldin!");
}
derleyip çalıştırdığımızda ise karşımıza şu mesaj çıkacaktır
helloworld.rs:2:4: 2:21 error: unresolved name: io::bu_satırı_bas
helloworld.rs:2 io::bu_satırı_bas("Merhaba Dünya! Rust’a hoşgeldin!");
"" ^~~~~~~~~~~~~~~~~
error: aborting due to previous error
Bu hatanın sebebi ise bu_satırı_bas isimli bir fonksiyonun olmamasıdır.
DeğişkenlerRust’ta değişkenler başta bahsettiğimiz gibi tip tanımlamasına bağlı şekilde ad-
landırılıp hafızada yer edinirler. Rust’ta değişkenler iki tiptir mutable(değişebilen) ve immutable(değişmeyen) değişkenler.
Immutable(Değişmez) DeğişkenlerEğer tipini Rust’ın belirlemesini istediğiniz ve değişmez olmasını istediğiniz bir
değişken varsa tanımlama şu şekildedir:
11
let merhaba = "merhabalar"
Rust’ta değişkenler varsayılan olarak manipüle edilemez haldedir. Nasıl oluyor da değişken oluyorlar? sorusunun cevabı ise dilin oluşturulma amacına bir referans niteliğinde-dir Güvenli thread oluşumu(Thread-safe) özelliği bu yetenekten ileri gelir.
Mutable(Değişen) DeğişkenlerTanımlandıklarında C’deki herhangi bir sıradan lokal değişkenden pek farkları
yoktur. Şu şekilde tanımlanırlar:
let mut toplam = 0;
görüldüğü üzere mut keyword’ü değişkenin mutable olacağını ve değişebilir şekilde yaratılması gerektiğini belirtmekte kullanılır. Mutable değişkenlerin kul-lanımına bir örnek vermek gerekirse şöyle bir örnek verebiliriz:
fn main() {
let mut çevrim = 0;
"while (çevrim <= 10){
"" io::println("harika");
"" çevrim+=1;
"}
}
Tip TanımlamalarıTip tanımlamalarında tip ise C’deki gibi başta prefix (önek şeklinde) belirtil-
mez. Bunun yerine ikinoktadan sonra belirtilir. Örnek olarak;
let karpuz: float = 57.8;
let kavun = karpuz * 10.0;
let karpuz: int = 50;
io::println(fmt!("%d", monster_size));
12
İlk değişken olan karpuz kavun’u oluşturmak için kullanılmıştır. Görevi bittik-ten sonra yeniden farklı bir tip ile yaratılabilir. Ama bu kodu derlediğimizde bize kavun ve karpuz’u kullanmadığımızı söyleyen bir uyarı gelecektir. Bu bize son kar-puzu(integer olarak deklare ettiğimiz) bir işlemde kullanmadığımızı ve immutable olarak oluşturduğumuz kavun’u da bir işleme sokmadığımızı söylemektedir. Bu uyarıdan kurtulmak adına kullanmadığınız değişkenlerin başına “_” koymanız ye-terlidir.
Rust’ta tanımlayıcılar C’deki gibi alfabetik karakter veya alttan çizgi ile başlar-lar ve yine C’deki gibi numaralar, alfabetik karakterler ve alttan çizgi kombinasyon-ları ile devam edebilirler. Rust’ta tanımlayıcı yazım konvansiyonu ilk harfin küçük ol-ması ve gerekli yerlerde(kelimeler arasında vb.) alttan çizgi kullanılması üzerinedir. Ör-nek olarak:
let yakışıklı_değişken = 100;
verilebilir. Fakat yeni tip tanımlamaları bu konvansiyonu kullanmaz, bunun yerine camelCasing dediğimiz ilk harfi küçük sonraki her kelimenin ilk harfi büyük olma koşuluna uyarlar, örnek bir yeni tip tanımlaması ise şu şekildedir:
type yeniBirTipTanımlaması = int;
Rust’ta kod yazarken Türkçe karakter kullanabilirsiniz. Bu size taşınabilirlikte de kullanılabilirlikte de sorun çıkarmaz.
İfade Yapısı/SentaksRust kendisi değer döndürebilen ve değeri yerleştirebilen bir yapıya sahiptir. Bu
yapı tanımlayıcıların tekrar tekrar kullanılmasını önlemekle beraber return key-word’ünde bile blok yazmamızı da sağlamaktadır. Şimdi C’deki bir yapıyı Rust’ta gösterelim.
let şeker;
if item == "reçel" {
şeker = 3.50;
} else if item == "kek" {
13
şeker = 2.25;
} else {
şeker = 2.00;
}
Bu stil C’deki tanımlamanın birebir uyarlamasıdır. Bunun yerine biz Rust’ta bu yapıyı yazmak istesek daha güzel ve mantıksal bir yol izleyerek;
let şeker =
if item == "reçel" {
3.50
} else if item == "kek" {
2.25
} else {
2.00
};
bu şekilde tanımlayacaktık. Bu bize sadece atamayı değil aynı zamanda içeride so-nucu oluşturabilecek bir fonksiyonu da kullanabilmemizi sağlıyor. Dikkat ettiyseniz 2. örnekte noktalıvirgül sözkonusu değildir son bloktaki noktalı virgül tüm blok zin-cirinin başlıbaşına bir kod olarak çalıştırılmasını tetikler, bu bize esneklikte sağlar aynı zamanda örnek olarak 3.50 değeri yerine 3.50 değerini oluşturan bir fonksiyo-nun varolabilmesi hatta bu fonksiyonun diğer durumlara da bağlı olabilen tek para-metreli bir fonksiyon da olabilmesi gibi. Rust işte bu şekilde bizim yapabilecek-lerimizi esneterek ve kısaltarak kolaylık sağlamaktadır. Aynı zamanda Rust işlemci üzerindeki boş işlemci vaktini paralel threadler çalıştırarak minimize etmektedir.
Yukarıdaki örnekte 3.50, 2.25 ve 2.00 olarak değer atadığımız satırlar eğer “;” ile kullanılsalardı, ifade mekanizması çalışmayacaktı. Bunun nedeni bahsettiğimiz bloklamadır. Böyle bir atama yine de çalışır fakat atanma değişkene döndürülüy-orsa nil fonksiyona döndürülüyorsa void olur. Bu da istediğimiz sonucu vermez.
14
Değişkenler için let, fonksiyonlar için fn , trait tanımlamaları, enumlar
ve constantlar harici dil dahilinde kalan herşey ifade kapsamına girmektedir.
Rust’ta ifade olması için fonksiyon içeriği olmak bile yeterlidir. Örneğin;
fn dört_döndür(x: int) -> bool {
x==4
}
return ifadesine gerek duyulmadan alınan değer return değeri amacıyla kullanıla-caktır.
Eğer satırlar atama, binary veya unary operasyonlar için kullanılmıyor ve fonksi-yonlar kullanılıyorsa;
let x = foo();
if x {
bar();
} else {
baz();
}
Bu şekilde fonksiyon sonrası “;” ifadesi kullanılarak yazılırlar. Burada önemli olan şu noktadır: eğer biz bu fonksiyonlardan bir değer döndürmüyorsak ve fonksiyon-larımız C’deki void fonksiyonlar gibi ise(ki bu Rust’ta nil-type’a karşılık gelir) her ifade çevriminin sonuna yukarıda belirttiğimiz gibi bir “;” konulur.
Bu durumlar “;”ün konulduğu durumlardır. Konulmadığı durumların genel özelliği ise kesin bir değer döndürüp bu değer’in nil’den farklı olduğu durumlar ol-maktadır. İşte buna bir örnek ise:
fn bar() -> int {
"let a = 9;
"return a;
15
}
fn baz() -> int {
"return 10;
}
fn main() {
"let x = false;
"io::println(fmt!("Cevap %d",
"if x {
"bar()
"} else {
"baz()
"}));
}
Görüldüğü üzere bar() ve baz() değer döndürdükleri için “;” koymuyoruz hatta blok sonuna da koymamamızın nedeni println()’in onu hesaplama girişiminde bu-lunacağıdır.
16
Veri TipleriTipler genel olarak C’deki gibidirler ve şu şekilde gösterilebilirler:
Kompozit tipler de genel yapıları itibariyle aşağıdaki şekildedir. Burada her T bir başka tipi göstermektedir.
Bazı tipler hiçbir zaman pointer olmadan değiştirilemezler. Örneğin string ola-rak tanımlanmış değerlere ~, @ ve & işaretçilerinden biri kullanılmadan erişim yapılamaz. Bu kullanıma sahip olan tipler genellikle dinamik genişleyebilen(karak-ter, saf veri vb. ile) tiplerdir.
17
Tipler Açıklama() Bir tek değer içeren, Birim
bool true veya false değerlerine sahip olan, Boolean
int, uintÜzerinde çalıştığı makinenin
tanımlamalarına bağlı işaretli ve işaretsiz tamsayılar, signed & unsigned integer
i8, i16, i32, i64 Belirli bit büyüklüğünde işaretli tamsayılar, signed sized integers
u8, u16, u32, u64 Belirli bit büyüklüğünde işaretsiz tamsayılar, unsigned sized integers
floatÜzerinde çalıştığı makinenin üzerinde
genel konvansiyonda en iyi çalışabilecek en büyük ondalıklı sayı, float
f32, f64 Belirli bit büyüklüğünde ondalıklı sayılar, floating type
char Unicode karakter setini kullanan karakter (32 bit)
Kompozit Tipler Açıklama[T * N] Vektör (Vektör diğer dillerdeki diziyi
temsil eder)[mut T * N] Mutable vektör
(T1, T2) Tuple tipleri&T, ~T, @T Pointer tipleri
Dinamik genişleyen tiplere ise şu örnekleri verebiliriz:
Fonksiyon tiplerinde değer döndürme -> işareti ile belirtilir fonksiyon deklerasy-onunda ise şu şekildedir:
fn foo() -> bool { }
Rust’ın en güzel özelliklerinden biri de anlamsız veya işinize yaramayan bir değer döndürmeniz gerektiğinde -> () şeklinde bir yazım yapabilmenizdir. Bunun yanında bu yazım yapılmasa da olur.
Yeni tip tanımlamaları takmaad olarak da kullanılabilir ve şu şekilde tanım-lanır:
type BüyükVeri = uint;
Bu tanımlama BüyükVeri tipiyle uint tipini aynı bağlamda kullanabiliriz. Burada önemli olan kısım bu tanımlamada BüyükVeri ve uint tiplerinin birbirinden bağımsız olduk-larını sanıp dönüştürülemeyeceğini düşünmektir, fakat durum böyle değildir veriler birbirl-erine dönüştürülebilirler çünkü tipler saklanırken yapılarına göre saklanır BüyükVeri’nin özünde uint olduğu bilinmektedir.
Rust’ta tiplerimizin ismen bağlanmasını ve yapısallıkla ilişki kurmamasını istiy-orsak struct ve enum anahtar kelimelerini kullanabiliriz.
18
Dinamik Genişleyen Tipler Açıklamafn(a: T1, b: T2) -> T3 Fonksiyon tipleri
str String(Katar) tipleri (UTF-8)
[T] Uzunluğu bilinmeyen vektör (diğer adıyla dilim)
[mut T] Uzunluğu bilinmeyen mutable vektör
LiterallerIntegerlar(tamsayı) decimal, hexadecimal veya binary formatlarda yazılabilirler.
Bu yazımların tamamına integral tip denir. Tüm integral tipler son ek’e sahiptir ve literalin çeşidini belirler. int için i, uint için u, int8 için i8 tipi gibi.
Literaller konulmazsa Rust fonksiyon argümanları ve tip tanımlamalarıyla lit-eral olmaksızın tanımlamayı tahmin eder ve ona göre yorumlar genellikle bu yo-rumlama sisteme en yakın varsayılan üzerinedir. Örnek olarak;
let a = 1; // a varsayılan olarak int atanır
let b = 10i; // b int oldu, i son ekinden dolayı
let c = 100u; // c uint oldu
let d = 1000i32;
verilebilir.
SabitlerDerleme zamanı sabitleri const anahtar kelimesi ile tanımlanır.
const PAROLAM: int = 12345;
const KATAR_PAROLAM: &static/str = "12345";
const EV_PAROLAM: int = PAROLAM + 1;
OperatörlerAritmetik operatörler
*, /, %, +, - (çarp, böl, mod al, topla, çıkar) ayrıca - unary operatör
olup sayıları negatif yapmakta kullanılır. C’deki gibi bit operatörleri >>, <<, &, |,
ve ^ ‘dir.
! tüm bitleri ters çevirir ve C’deki ~ operatörü gibi.Rust’ın karşılaştırma oper-atörleri C’deki karşılaştırma operatörleriyle aynıdır.
== , !=, <, >, <=, >=, &&, || gibi...
19
Tip dönüşümü yaparken Rust as operatörünü kullanır. Örnek olarak
let x: float = 4.0;
let y: uint = x as uint;
assert y == 4u;
Sentaks GenişletmeleriDilin saf haline entegre olmamış ama sonradan kütüphaneler yardımıyla dahil
edilmiş özelliklerdir. Şu anda std::core kütüphanesi bu genişletmeleri yeterli miktarda karşılamaktadır. C formatlamasının benzer özellikleri kütüphaneler yardımıyla alınmıştır. Katar formatlamanın geliştirilmesi gündemdedir.
io::println(fmt!("%s bence %d", "cevap", 43));
io::println(fmt!("Bu nedir %?", gizli_nesne));
Yukarıdaki örneğimizde %? tüm tipleri içine alabilen ve manipüle ederek for-
mata uyduran ibaredir. Dikkat ederseniz fmt!() olmadan formatlama yapılama-maktadır. Bu fonksiyon çekirdek kütüphaneyi kullanarak formatlama yapacaksak mecburidir. Kendi sentaks genişletmelerinizi de yazabilirsiniz. Rust buna izin verir. Bu genişletmelerin genel adı makrolardır.
20
B Ö L Ü M 3
Program Akışı
Kontrol YapılarıKoşullu Yapılar
If yapısını önceki bölümlerde gözden geçirdik kısa bir örnekle özetleyelim:
if false {
io::println("yanlış olan kısım");
} else if true {
io::println("doğru yer");
} else {
io::println("ne doğru ne yanlış");
}
Fakat eğer her blokta değer döndürülme mekanizması şeklinde çalışıyorsa if yapısı tüm blok içlerindeki değerler kesinlikle aynı tipte olmak zorundadır. Örnek olarak:
fn signum(x: int) -> int {
if x < 0 { -1 }
else if x > 0 { 1 }
else { return 0 }
}
21
Örnek EşlemeRust örnek eşleme mekanizmasını diğer mekanizmalara tercih eder bundan do-
layı örnek eşleme mekanizması gelişmiştir. match mekanizması C’deki
switch’in bir benzeri olabileceği gibi return durumlarında döndürülecek seçe-neklerin belirlenmesini sağlamaktadır.
match numara {
0 => io::println("sıfır"),
1 | 2 => io::println("bir veya iki"),
3..10 => io::println("3ten 10a kadar"),
_ => io::println("geri kalan tüm durumlar")
}
C’deki gibi bir case yapıldıktan sonra kaldığı yerden devam etmez. Bu yapı sabittir ve sadece bir dalı yapar ve işlemini bitirir. ( _ ) wildcard eşlemesi olarak ad-
landırılan ifadedir ve anlamı “en az bir eşleşme”dir. ( * ) ise “enum tanımla-masında bir veya daha fazla eşleşme” anlamına gelmektedir.
Kollar her zaman => işaretiyle tanımlanmasına başlanır.
match numara {
0 => { io::println("sıfır") }
_ => { io::println("başka birşey") }
}
numara değeri 0’a eşitse “sıfır” string’ini ekrana bastırırken diğer tüm girdi du-rumlarında “başka birşey” çıktısını verecektir.
match tüm kolları arar ve tüm olası durumları koşul üzerinden geçirir. match’in en önemli işlevlerinden biri değişken isimleri ile verilerin bağlanabilmesi-dir. Aşağıdaki örnekte (veri1, veri2) tuple veritipine örnektir.
22
fn angle(vector: (float, float)) -> float {
let pi = float::consts::pi;
match vector {
(0f, y) if y < 0f => 1.5 * pi,
(0f, y) => 0.5 * pi,
(x, y) => float::atan(y / x)
}
}
Değişkenin ismi örnekteki veriyle eşlenmiştir. İlk kolda görülen ve y yazılan yerde bulunan veri kontrol ve manipüle edilebilir. Aynı zamanda üçüncü koldaki (x, y) örneği tamamen örnek eşlemeye yönelik bir tuple’dır. Her match kolu
if ile takip ediliyorsa bu if ifadesine örnek bekçisi denir. Örnek bekçisi ifadenin doğruluğunu kontrol ettikten sonra koldaki ifadeyi yapmaya yönelir. İfade ister değer döndürme olsun ister bir fn döndürme tipine bakılarak işlem yapılır, ne olduğuna bakılmaz.
DöngülerRust’ta döngü yapımı sadece while ile sağlanabilir. Array kavramı vektör olarak
yer aldığı için vektör üzerinde iterasyon sadece bekçi içeren ifadeler ile yapılabilir. For döngüsü Rust için gelecekte planlanan bir özelliktir. While döngüsü yine C’den çok farklı olmamakla birlikte aşağıdaki gibidir:
let mut cake_amount = 8;
while cake_amount > 0 {
cake_amount -= 1;
}
Rust’ta while (true) ifadesi için geliştirilmiş özel bir sentaks vardır bu ifade
loop ‘tur. Sonsuz döngüyü ifade eder:
23
let mut x = 5;
loop {
x += x - 3;
if x % 5 == 0 { break; }
io::println(int::str(x));
}
Bu kod birkaç sayı yazdıktan sonra 5’e bölünebilen bir sayı bulduğunda sonsuz döngüden çıkacak şekilde yazılmıştır.
Veri YapılarıStructİlk olarak struct yapısıyla başlayabiliriz. Struct yapısı C’dekine benzer bir yapı
sergilemektedir hatta hafızada tutulma şekilleri aynıdır. Kullanımı C’deki kullanım şekliyle aynıdır.
struct Stack {
content: ~[int],
mut head: uint
}
Yıkıcı sentaks bir değeri yerine tanımlanmış başka bir değişkenle manipüle etmektir. Daha önce de bahsettiğimiz yıkıcı yapı structlar için de kullanılabilir. Örneğin;
match Noktam {
Nokta { x: 0.0, y: yy } => { io::println(yy.to_str());}
Nokta { x: xx, y: yy } => { io::println(xx.to_str() + " " + yy.to_str()); }
24
}
EnumerationEnumlar birden fazla şekilde gösterilebilirler. En basit gösterimlerinden biri;
enum Şekil {
Daire(Point, float),
Dikdörtgen(Point, Point)
}
şeklindedir. Argüman olarak atama yapılabildiği gibi sıradan C enumları gibi kendi içlerinde büyükten küçüğe indeks sıralaması yapan enumlar da vardır. Ör-nek olarak:
enum Yön {
Kuzey,
Güney,
Doğu,
Batı
}
Kuzey 0, Güney 1, Doğu 2 ve Batı 3 değerini almaktadır. Fakat diğer atamalı enumlarda bu tanımlama geçerli olmayıp her belirtme atamaya göre yapılır.
Dereferans(deref) işlemi de bir unary operatör olup enumlar üzerinde içerisin-deki değeri almalarını sağlamaktadır.
enum Ses { Ses (int) }
let ses_seviyesi: Ses = Ses(10);
let anlık_ses_seviyesi: int = *ses_seviyesi;
Başka bir içerikten bilgi alınması bu şekilde sağlanabilir.
25
Enumlar aynı zamanda örnek eşlemede de kullanılabilirler:
fn bu_noktadan_tarif(dir: Yön) -> Nokta {
match dir {
Kuzey => Point {x: 0f, y: 1f},
Doğu => Point {x: 1f, y: 0f},
Güney => Point {x: 0f, y: -1f},
Batı => Point {x: -1f, y: 0f}
}
}
TupleRust’ta tuplelar enumlar gibi çalışır dakat enumlar gibi alanadları yoktur.
Argümanlaştırma işlemi yapılır fakat bu işlemde 0 veya 1 argüman olarak verilemez. Enumda bu yapılırken tuple da bu yapılamaz. Örnek bir tuple ise şu şekildedir:
let mytup: (int, int, float) = (10, 20, 30.0);
match mytup {
(a, b, c) => log(info, a + b + (c as int))
}
Rust’a dair 0.4 versiyonuyla kesinleşmiş ve temele oturmuş özellikler ve yapılar bunlardır. Traitler, yeni döngüler, REPL(read evaluate print loop), Exception mekanizması gibi özellikler yeni yeni geliştirilmektedir. Ayrıca fonksiyonların saflığı ve saf olmamaları ve bu saflık yapısının nasıl olması gerektiği hakkında hala bir takım belirlenmemiş kısımlar vardır.
26