hacktricks/todo/rust-basics.md

520 lines
18 KiB
Markdown
Raw Normal View History

2024-02-10 18:14:16 +00:00
# Rust Temelleri
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
### Genel Tipler
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
Herhangi bir tipte olabilen bir değeri içeren bir yapı (struct) oluşturun.
2022-06-26 16:12:47 +00:00
```rust
struct Wrapper<T> {
2024-02-10 18:14:16 +00:00
value: T,
2022-06-26 16:12:47 +00:00
}
impl<T> Wrapper<T> {
2024-02-10 18:14:16 +00:00
pub fn new(value: T) -> Self {
Wrapper { value }
}
2022-06-26 16:12:47 +00:00
}
Wrapper::new(42).value
Wrapper::new("Foo").value, "Foo"
```
### Option, Some & None
2024-02-10 18:14:16 +00:00
Option türü, değerin Some (bir şey var) veya None türünde olabileceği anlamına gelir:
2022-06-26 16:12:47 +00:00
```rust
pub enum Option<T> {
2024-02-10 18:14:16 +00:00
None,
Some(T),
2022-06-26 16:12:47 +00:00
}
```
2024-02-10 18:14:16 +00:00
Option'un değerini kontrol etmek için `is_some()` veya `is_none()` gibi fonksiyonları kullanabilirsiniz.
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
### Makrolar
2022-06-27 08:23:29 +00:00
2024-02-10 18:14:16 +00:00
Makrolar, fonksiyonlardan daha güçlüdür çünkü manuel olarak yazdığınız kodun üzerine daha fazla kod üretmek için genişler. Örneğin, bir fonksiyon imzası, fonksiyonun sahip olduğu parametrelerin sayısını ve türünü bildirmelidir. Makrolar ise değişken sayıda parametre alabilir: `println!("hello")` bir argümanla veya `println!("hello {}", name)` iki argümanla çağrılabilir. Ayrıca, makrolar, derleyicinin kodun anlamını yorumlamadan önce genişletilir, bu nedenle bir makro, örneğin, belirli bir tür üzerinde bir özniteliği uygulayabilir. Bir fonksiyon yapamaz çünkü çalışma zamanında çağrılır ve bir öznitelik derleme zamanında uygulanmalıdır.
2022-06-27 08:23:29 +00:00
```rust
macro_rules! my_macro {
2024-02-10 18:14:16 +00:00
() => {
println!("Check out my macro!");
};
($val:expr) => {
println!("Look at this other macro: {}", $val);
}
2022-06-27 08:23:29 +00:00
}
fn main() {
2024-02-10 18:14:16 +00:00
my_macro!();
my_macro!(7777);
2022-06-27 08:23:29 +00:00
}
// Export a macro from a module
mod macros {
2024-02-10 18:14:16 +00:00
#[macro_export]
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
}
```
### Yinele
Yineleme, bir döngü kullanarak bir dizi veya koleksiyon üzerinde tekrarlayarak her bir öğeyi işlemek için kullanılan bir programlama tekniğidir. Rust dilinde, yineleme işlemi çeşitli yollarla gerçekleştirilebilir.
#### `for` Döngüsü
En yaygın kullanılan yineleme yöntemi, `for` döngüsüdür. Bu döngü, bir koleksiyonun her bir öğesini sırayla işlemek için kullanılır. Rust dilinde, `for` döngüsü aşağıdaki şekilde kullanılır:
```rust
for element in collection {
// Öğe üzerinde yapılacak işlemler
}
```
`element` değişkeni, her bir öğeyi temsil eder ve `collection` ise yinelemek istediğimiz koleksiyonu temsil eder.
#### `while` Döngüsü
`while` döngüsü, belirli bir koşul sağlandığı sürece tekrarlanan bir döngüdür. Rust dilinde, `while` döngüsü aşağıdaki şekilde kullanılır:
```rust
while condition {
// Koşul sağlandığı sürece yapılacak işlemler
}
```
`condition` ifadesi, döngünün tekrarlanmasını kontrol eden bir koşul ifadesidir.
#### `loop` Döngüsü
`loop` döngüsü, belirli bir koşul sağlanana kadar sürekli olarak tekrarlanan bir döngüdür. Rust dilinde, `loop` döngüsü aşağıdaki şekilde kullanılır:
```rust
loop {
// Sürekli olarak yapılacak işlemler
if condition {
break; // Döngüyü sonlandırmak için kullanılır
2022-06-27 08:23:29 +00:00
}
}
```
2024-02-10 18:14:16 +00:00
`break` ifadesi, döngüyü sonlandırmak için kullanılır ve belirli bir koşul sağlandığında döngüden çıkılır.
2022-06-27 08:23:29 +00:00
2024-02-10 18:14:16 +00:00
Yineleme, Rust dilinde programlama yaparken sık sık kullanılan bir tekniktir ve çeşitli döngü yapılarıyla gerçekleştirilebilir.
2022-06-27 08:23:29 +00:00
```rust
// Iterate through a vector
let my_fav_fruits = vec!["banana", "raspberry"];
let mut my_iterable_fav_fruits = my_fav_fruits.iter();
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
assert_eq!(my_iterable_fav_fruits.next(), None); // When it's over, it's none
2024-02-10 18:14:16 +00:00
2022-06-27 08:23:29 +00:00
// One line iteration with action
my_fav_fruits.iter().map(|x| capitalize_first(x)).collect()
// Hashmap iteration
for (key, hashvalue) in &*map {
for key in map.keys() {
for value in map.values() {
```
2024-02-10 18:14:16 +00:00
### Yinelemeli Kutu
2022-06-27 08:23:29 +00:00
2024-02-10 18:14:16 +00:00
Bir kutunun içinde başka bir kutu bulunabilir. Bu, yinelemeli bir kutu yapısı oluşturur. Yinelemeli kutular, veri yapılarını daha karmaşık hale getirmek için kullanılabilir.
2022-06-27 08:23:29 +00:00
2024-02-10 18:14:16 +00:00
Yinelemeli kutular, birbirine bağlı kutuların bir ağacını oluşturur. Her kutu, içinde başka kutular veya veriler bulunabilecek bir dizi alan içerir. Bu yapı, verileri hiyerarşik bir şekilde düzenlemek için kullanılabilir.
Yinelemeli kutular, özyinelemeli fonksiyonlar gibi davranabilir. Bir kutu, içindeki diğer kutuları veya verileri işleyebilir ve bu işlemi yineleyebilir. Bu, bir algoritmanın yinelemeli olarak çalışmasını sağlar.
Yinelemeli kutular, programlama dillerinde ve veri tabanlarında sıklıkla kullanılır. Örneğin, bir dosya sistemi, yinelemeli kutuların bir örneğidir. Bir klasör, içinde başka klasörler veya dosyalar bulundurabilir. Bu şekilde, dosyalar ve klasörler hiyerarşik bir yapı oluşturur.
2022-06-27 08:23:29 +00:00
```rust
enum List {
2024-02-10 18:14:16 +00:00
Cons(i32, List),
Nil,
2022-06-27 08:23:29 +00:00
}
let list = Cons(1, Cons(2, Cons(3, Nil)));
```
2024-02-10 18:14:16 +00:00
#### eğer
2022-06-27 08:23:29 +00:00
2024-02-10 18:14:16 +00:00
The `if` statement is used to execute a block of code only if a certain condition is true. It has the following syntax:
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
```rust
if condition {
// code to be executed if the condition is true
}
```
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
The `condition` can be any expression that evaluates to a boolean value (`true` or `false`). If the condition is true, the code inside the block will be executed. If the condition is false, the code inside the block will be skipped.
Here's an example:
```rust
let number = 5;
if number > 0 {
println!("The number is positive");
}
```
In this example, the code inside the `if` block will be executed because the condition `number > 0` is true. The output will be `The number is positive`.
#### else
The `else` statement is used to execute a block of code if the condition of the `if` statement is false. It has the following syntax:
```rust
if condition {
// code to be executed if the condition is true
} else {
// code to be executed if the condition is false
}
```
Here's an example:
```rust
let number = -5;
if number > 0 {
println!("The number is positive");
} else {
println!("The number is negative");
}
```
In this example, the condition `number > 0` is false, so the code inside the `else` block will be executed. The output will be `The number is negative`.
#### else if
The `else if` statement is used to chain multiple conditions together. It has the following syntax:
```rust
if condition1 {
// code to be executed if condition1 is true
} else if condition2 {
// code to be executed if condition1 is false and condition2 is true
} else {
// code to be executed if both condition1 and condition2 are false
}
```
Here's an example:
```rust
let number = 0;
if number > 0 {
println!("The number is positive");
} else if number < 0 {
println!("The number is negative");
} else {
println!("The number is zero");
}
```
In this example, the condition `number > 0` is false, and the condition `number < 0` is also false, so the code inside the `else` block will be executed. The output will be `The number is zero`.
2022-06-26 16:12:47 +00:00
```rust
let n = 5;
if n < 0 {
2024-02-10 18:14:16 +00:00
print!("{} is negative", n);
2022-06-26 16:12:47 +00:00
} else if n > 0 {
2024-02-10 18:14:16 +00:00
print!("{} is positive", n);
2022-06-26 16:12:47 +00:00
} else {
2024-02-10 18:14:16 +00:00
print!("{} is zero", n);
2022-06-26 16:12:47 +00:00
}
```
2024-02-10 18:14:16 +00:00
#### eşleşme
`match` ifadesi, bir değerin farklı durumlarına göre farklı işlemler yapmak için kullanılır. Bu ifade, bir değeri birden fazla desenle karşılaştırır ve eşleşen desene göre belirli bir kod bloğunu çalıştırır.
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
```rust
match deger {
desen1 => {
// desen1 ile eşleşirse burası çalışır
},
desen2 => {
// desen2 ile eşleşirse burası çalışır
},
_ => {
// hiçbir desenle eşleşmezse burası çalışır
}
}
```
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
`_` (alt çizgi) deseni, herhangi bir desenle eşleşmeyen durumları temsil eder. Bu, `match` ifadesindeki bir desenin tam olarak eşleşmediği durumlarda çalışacak olan bir "varsayılan" blok sağlar.
2022-06-26 16:12:47 +00:00
```rust
match number {
2024-02-10 18:14:16 +00:00
// Match a single value
1 => println!("One!"),
// Match several values
2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
// TODO ^ Try adding 13 to the list of prime values
// Match an inclusive range
13..=19 => println!("A teen"),
// Handle the rest of cases
_ => println!("Ain't special"),
2022-06-26 16:12:47 +00:00
}
let boolean = true;
// Match is an expression too
let binary = match boolean {
2024-02-10 18:14:16 +00:00
// The arms of a match must cover all the possible values
false => 0,
true => 1,
// TODO ^ Try commenting out one of these arms
2022-06-26 16:12:47 +00:00
};
```
2024-02-10 18:14:16 +00:00
#### döngü (sonsuz)
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
An infinite loop is a loop that continues indefinitely until it is explicitly terminated. It is often used in programming to create processes or tasks that need to run continuously without an end condition. In Rust, you can create an infinite loop using the `loop` keyword.
2022-06-26 16:12:47 +00:00
```rust
loop {
2024-02-10 18:14:16 +00:00
// Code to be executed repeatedly
}
```
In the example above, the code inside the loop will be executed repeatedly until the loop is explicitly terminated. To terminate the loop, you can use the `break` keyword.
```rust
loop {
// Code to be executed repeatedly
if condition {
break; // Terminate the loop
2022-06-26 16:12:47 +00:00
}
}
```
2024-02-10 18:14:16 +00:00
In the second example, the loop will continue executing the code inside until the `condition` is met, at which point the loop will be terminated using the `break` keyword.
Infinite loops can be useful in certain scenarios, such as when creating server applications that need to listen for incoming connections continuously or when implementing background tasks that need to run indefinitely. However, it is important to ensure that there is a way to terminate the loop to prevent it from running indefinitely and consuming excessive resources.
```rust
loop {
count += 1;
if count == 3 {
println!("three");
continue;
}
println!("{}", count);
if count == 5 {
println!("OK, that's enough");
break;
}
}
```
2022-06-26 16:12:47 +00:00
#### while
2024-02-10 18:14:16 +00:00
`while` döngüsü, belirli bir koşul doğru olduğu sürece bir bloğu tekrar tekrar çalıştırmak için kullanılır. Döngü, koşul yanlış olduğunda durur.
2022-06-26 16:12:47 +00:00
```rust
2024-02-10 18:14:16 +00:00
while koşul {
// Kod bloğu
2022-06-26 16:12:47 +00:00
}
```
2024-02-10 18:14:16 +00:00
Yukarıdaki örnekte, `koşul` doğru olduğu sürece kod bloğu tekrar tekrar çalıştırılır. `koşul` yanlış olduğunda döngü sona erer ve program devam eder.
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
Örneğin, aşağıdaki kod parçası, 1'den 5'e kadar olan sayıları ekrana yazdırır:
```rust
let mut i = 1;
while i <= 5 {
println!("{}", i);
i += 1;
}
```
Bu kod parçası, `i` değişkeninin değeri 1'den başlayarak her döngüde 1 artırılır ve `i` değeri 5'e eşit veya daha büyük olduğunda döngü sona erer. Her döngüde, `i` değeri ekrana yazdırılır. Sonuç olarak, 1, 2, 3, 4 ve 5 ekrana yazdırılır.
```rust
let mut n = 1;
while n < 101 {
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
n += 1;
}
```
#### için
2022-06-26 16:12:47 +00:00
```rust
for n in 1..101 {
2024-02-10 18:14:16 +00:00
if n % 15 == 0 {
println!("fizzbuzz");
} else {
println!("{}", n);
}
2022-06-26 16:12:47 +00:00
}
// Use "..=" to make inclusive both ends
for n in 1..=100 {
2024-02-10 18:14:16 +00:00
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
2022-06-26 16:12:47 +00:00
}
// ITERATIONS
let names = vec!["Bob", "Frank", "Ferris"];
//iter - Doesn't consume the collection
for name in names.iter() {
2024-02-10 18:14:16 +00:00
match name {
&"Ferris" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
}
2022-06-26 16:12:47 +00:00
}
//into_iter - COnsumes the collection
for name in names.into_iter() {
2024-02-10 18:14:16 +00:00
match name {
"Ferris" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
}
2022-06-26 16:12:47 +00:00
}
//iter_mut - This mutably borrows each element of the collection
for name in names.iter_mut() {
2024-02-10 18:14:16 +00:00
*name = match name {
&mut "Ferris" => "There is a rustacean among us!",
_ => "Hello",
}
2022-06-26 16:12:47 +00:00
}
```
2024-02-10 18:14:16 +00:00
#### eğer let
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
```rust
if let Some(value) = optional_value {
// Code to execute if optional_value is Some
} else {
// Code to execute if optional_value is None
}
```
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
Bu yapı, bir `Option` değerinin içeriğini kontrol etmek için kullanılır. Eğer `optional_value` `Some` ise, `value` değişkenine atama yapılır ve `Some` durumunda çalıştırılacak kod bloğu çalıştırılır. Eğer `optional_value` `None` ise, `None` durumunda çalıştırılacak kod bloğu çalıştırılır.
2022-06-26 16:12:47 +00:00
```rust
let optional_word = Some(String::from("rustlings"));
if let word = optional_word {
2024-02-10 18:14:16 +00:00
println!("The word is: {}", word);
2022-06-26 16:12:47 +00:00
} else {
2024-02-10 18:14:16 +00:00
println!("The optional word doesn't contain anything");
2022-06-26 16:12:47 +00:00
}
```
#### while let
2024-02-10 18:14:16 +00:00
`while let` ifadesi, bir desen eşleşmesi kullanarak bir değerin bir desene uyması durumunda bir döngüyü çalıştırmak için kullanılır. Bu ifade, bir desenin eşleştiği sürece döngüyü tekrar tekrar çalıştırır.
```rust
while let Some(value) = iterator.next() {
// Döngü gövdesi
}
```
Yukarıdaki örnekte, `iterator.next()` metodu bir `Option` değeri döndürür. Eğer bu değer `Some` ise, `value` değişkenine atama yapılır ve döngü gövdesi çalıştırılır. Eğer değer `None` ise, döngü sona erer.
Bu yapı, bir koleksiyonun elemanlarını işlemek veya bir değerin belirli bir duruma ulaşmasını beklemek gibi durumlarda kullanışlıdır.
2022-06-26 16:12:47 +00:00
```rust
let mut optional = Some(0);
// This reads: "while `let` destructures `optional` into
// `Some(i)`, evaluate the block (`{}`). Else `break`.
while let Some(i) = optional {
2024-02-10 18:14:16 +00:00
if i > 9 {
println!("Greater than 9, quit!");
optional = None;
} else {
println!("`i` is `{:?}`. Try again.", i);
optional = Some(i + 1);
}
// ^ Less rightward drift and doesn't require
// explicitly handling the failing case.
2022-06-26 16:12:47 +00:00
}
```
### Traits
2024-02-10 18:14:16 +00:00
Bir tür için yeni bir yöntem oluşturun
2022-06-26 16:12:47 +00:00
```rust
trait AppendBar {
2024-02-10 18:14:16 +00:00
fn append_bar(self) -> Self;
2022-06-26 16:12:47 +00:00
}
impl AppendBar for String {
2024-02-10 18:14:16 +00:00
fn append_bar(self) -> Self{
format!("{}Bar", self)
}
2022-06-26 16:12:47 +00:00
}
let s = String::from("Foo");
let s = s.append_bar();
println!("s: {}", s);
```
2024-02-10 18:14:16 +00:00
### Testler
Testler, yazılım geliştirme sürecinde önemli bir rol oynar. Bir yazılımın doğru çalıştığından emin olmak için testler kullanılır. Testler, yazılımın beklenen sonuçları üretip üretmediğini kontrol etmek için kullanılır. Testler, hataları tespit etmek ve düzeltmek için kullanılır. Yazılımın güvenilirliğini artırmak ve kullanıcı deneyimini iyileştirmek için testler yapılır.
Testler, genellikle bir test çerçevesi kullanılarak yapılır. Test çerçeveleri, test senaryolarını otomatikleştirmek ve test sürecini kolaylaştırmak için kullanılır. Testler, birim testleri, entegrasyon testleri, kabul testleri ve performans testleri gibi farklı kategorilere ayrılabilir. Her bir test kategorisi, farklı bir amaca hizmet eder ve farklı bir test stratejisi gerektirir.
Testler, yazılımın hatalarını tespit etmek için kullanılır. Hatalar, yazılımın beklenen sonuçları üretmediği durumlarda ortaya çıkar. Testler, hataları tespit etmek ve düzeltmek için kullanılır. Testler, yazılımın güvenilirliğini artırmak ve kullanıcı deneyimini iyileştirmek için yapılır.
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
Testler, yazılımın doğru çalıştığından emin olmak için kullanılır. Testler, yazılımın beklenen sonuçları üretip üretmediğini kontrol etmek için kullanılır. Testler, yazılımın doğru çalıştığını doğrulamak için yapılır.
2022-06-26 16:12:47 +00:00
2024-02-10 18:14:16 +00:00
Testler, yazılımın performansını ölçmek için kullanılır. Performans testleri, yazılımın belirli bir yük altında nasıl performans gösterdiğini değerlendirmek için yapılır. Performans testleri, yazılımın hızını, ölçeklenebilirliğini ve dayanıklılığını test etmek için kullanılır.
Testler, yazılımın güvenliğini değerlendirmek için kullanılır. Güvenlik testleri, yazılımın potansiyel güvenlik açıklarını tespit etmek ve düzeltmek için yapılır. Güvenlik testleri, yazılımın saldırılara karşı ne kadar dirençli olduğunu değerlendirmek için kullanılır.
Testler, yazılımın uyumluluğunu kontrol etmek için kullanılır. Uyumluluk testleri, yazılımın farklı platformlarda ve ortamlarda nasıl çalıştığını değerlendirmek için yapılır. Uyumluluk testleri, yazılımın farklı işletim sistemleri, tarayıcılar ve cihazlarla uyumlu olup olmadığını kontrol etmek için kullanılır.
Testler, yazılımın kullanılabilirliğini değerlendirmek için kullanılır. Kullanılabilirlik testleri, yazılımın kullanıcı dostu olduğunu ve kullanıcıların ihtiyaçlarını karşıladığını kontrol etmek için yapılır. Kullanılabilirlik testleri, yazılımın kullanıcı arayüzünü, gezinme kolaylığını ve kullanıcı deneyimini değerlendirmek için kullanılır.
Testler, yazılımın kalitesini değerlendirmek için kullanılır. Kalite testleri, yazılımın belirli kalite standartlarını karşılayıp karşılamadığını kontrol etmek için yapılır. Kalite testleri, yazılımın doğruluğunu, güvenilirliğini ve performansını değerlendirmek için kullanılır.
2022-06-26 16:12:47 +00:00
```rust
#[cfg(test)]
mod tests {
2024-02-10 18:14:16 +00:00
#[test]
fn you_can_assert() {
assert!(true);
assert_eq!(true, true);
assert_ne!(true, false);
}
2022-06-27 08:23:29 +00:00
}
```
2024-02-10 18:14:16 +00:00
### Eşitleme (Threading)
2022-06-27 08:23:29 +00:00
#### Arc
2024-02-10 18:14:16 +00:00
Bir Arc, nesneye daha fazla referans oluşturmak için Clone kullanabilir ve bunları thread'lere iletebilir. Son referansın bir değeri işaret ettiği zaman kapsam dışına çıktığında, değişken düşer.
2022-06-27 08:23:29 +00:00
```rust
use std::sync::Arc;
let apple = Arc::new("the same apple");
for _ in 0..10 {
2024-02-10 18:14:16 +00:00
let apple = Arc::clone(&apple);
thread::spawn(move || {
println!("{:?}", apple);
});
2022-06-27 08:23:29 +00:00
}
```
2024-02-10 18:14:16 +00:00
#### İş Parçacıkları
2022-06-27 08:23:29 +00:00
2024-02-10 18:14:16 +00:00
Bu durumda, iş parçacığına değiştirebileceği bir değişken geçireceğiz.
2022-06-27 08:23:29 +00:00
```rust
fn main() {
2024-02-10 18:14:16 +00:00
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let status_shared = Arc::clone(&status);
thread::spawn(move || {
for _ in 0..10 {
thread::sleep(Duration::from_millis(250));
let mut status = status_shared.lock().unwrap();
status.jobs_completed += 1;
}
});
while status.lock().unwrap().jobs_completed < 10 {
println!("waiting... ");
thread::sleep(Duration::from_millis(500));
}
2022-06-26 16:12:47 +00:00
}
```
2024-02-10 18:14:16 +00:00