Diziler

Bir dizi, aynı türden elemanların bir koleksiyonudur. ArrayTrait trait'ini çekirdek kütüphaneden kullanarak dizi metodları oluşturabilir ve kullanabilirsiniz.

Dikkat edilmesi gereken önemli bir nokta, dizilerin sınırlı modifikasyon seçeneklerine sahip olmasıdır. Diziler, aslında değerleri değiştirilemeyen kuyruklardır. Bu, bir bellek yuvasına yazıldıktan sonra, üzerine yazılamayacağı ancak ondan okunabileceği gerçeğiyle ilgilidir. Bir dizinin sonuna yalnızca eleman ekleyebilir ve önünden eleman çıkarabilirsiniz.

Dizi Oluşturma

Creating an array is done with the ArrayTrait::new() call. Here's an example of creating an array and appending 3 elements to it:

fn main() {
    let mut a = ArrayTrait::new();
    a.append(0);
    a.append(1);
    a.append(2);
}

Gerekirse, dizi örneğini oluştururken dizinin içindeki elemanların beklenen türünü bu şekilde geçirebilir veya değişkenin türünü açıkça tanımlayabilirsiniz.

let mut arr = ArrayTrait::<u128>::new();
let mut arr:Array<u128> = ArrayTrait::new();

Bir Diziyi Güncelleme

Elemanları Ekleme

Bir dizinin sonuna bir eleman eklemek için append() yöntemini kullanabilirsiniz:

fn main() {
    let mut a = ArrayTrait::new();
    a.append(0);
    a.append(1);
    a.append(2);
}

Elemanları Kaldırma

pop_front() metodunu kullanarak bir diziden yalnızca ön taraftaki elemanları çıkarabilirsiniz. Bu metod, kaldırılan elemanı içeren bir Option veya dizi boşsa Option::None döndürür.

fn main() {
    let mut a = ArrayTrait::new();
    a.append(10);
    a.append(1);
    a.append(2);

    let first_value = a.pop_front().unwrap();
    println!("The first value is {}", first_value);
}

Yukarıdaki kod, eklenen ilk elemanı çıkardığımız için The first value is 10 yazdıracaktır.

Cairo'da, bellek değişmezdir, bu da ekledikten sonra bir dizinin elemanlarını değiştirmenin mümkün olmadığı anlamına gelir. Bir dizinin sonuna yalnızca eleman ekleyebilir ve bir dizinin önünden eleman çıkarabilirsiniz. Bu işlemler, bellek hücrelerini doğrudan değiştirmek yerine işaretçileri güncellemeyi içerdiğinden, bellek mutasyonu gerektirmez.

Bir Diziden Eleman Okuma

Dizi elemanlarına erişmek için, farklı türler döndüren get() veya at() dizi metodlarını kullanabilirsiniz. arr.at(index) kullanmak, alt dizin operatörü arr[index] kullanmakla eşdeğerdir.

get() Method

The get function returns an Option<Box<@T>>, which means it returns an option to a Box type (Cairo's smart-pointer type) containing a snapshot to the element at the specified index if that element exists in the array. If the element doesn't exist, get returns None. This method is useful when you expect to access indices that may not be within the array's bounds and want to handle such cases gracefully without panics. Snapshots will be explained in more detail in the "References and Snapshots" chapter.

İşte get() yöntemiyle bir örnek:

fn main() -> u128 {
    let mut arr = ArrayTrait::<u128>::new();
    arr.append(100);
    let index_to_access =
        1; // Change this value to see different results, what would happen if the index doesn't exist?
    match arr.get(index_to_access) {
        Option::Some(x) => {
            *x
                .unbox() // Don't worry about * for now, if you are curious see Chapter 4.2 #desnap operator
            // It basically means "transform what get(idx) returned into a real value"
        },
        Option::None => { panic!("out of bounds") },
    }
}

at() Method

The at function, and its equivalent the subscripting operator, on the other hand, directly return a snapshot to the element at the specified index using the unbox() operator to extract the value stored in a box. If the index is out of bounds, a panic error occurs. You should only use at when you want the program to panic if the provided index is out of the array's bounds, which can prevent unexpected behavior.

fn main() {
    let mut a = ArrayTrait::new();
    a.append(0);
    a.append(1);

    // using the `at()` method
    let first = *a.at(0);
    assert!(first == 0);
    // using the subscripting operator
    let second = *a[1];
    assert!(second == 1);
}

Bu örnekte, first adlı değişken 0 değerini alacak çünkü bu, dizide 0 indeksindeki değerdir. second adlı değişken, dizide 1 indeksinden 1değerini alacak.

Özetle, sınırların dışındaki erişim girişimlerinde paniklemek istiyorsanız at kullanın ve bu tür durumları panik olmadan zarif bir şekilde ele almak istiyorsanız get kullanın.

Bir dizideki eleman sayısını belirlemek için len() metodunu kullanın. Dönüş değeri usize türündedir.

Bir dizinin boş olup olmadığını kontrol etmek istiyorsanız, is_empty() metodunu kullanabilirsiniz, bu metod dizi boşsa true, aksi takdirde false döndürür.

array! Macro

Bazen, derleme zamanında zaten bilinen değerlere sahip diziler oluşturmamız gerekiyor. Bunun temel yolu fazlalıklıdır. İlk olarak diziyi tanımlar ve sonra her bir değeri tek tek eklerdiniz. array! bu görevi iki adımı birleştirerek daha basit bir şekilde yapmanın yoludur. Derleme zamanında, derleyici makroyu genişleterek öğeleri sırayla ekleyen kodu oluşturacaktır.

Without array!:

    let mut arr = ArrayTrait::new();
    arr.append(1);
    arr.append(2);
    arr.append(3);
    arr.append(4);
    arr.append(5);

With array!:

    let arr = array![1, 2, 3, 4, 5];

Storing Multiple Types with Enums

If you want to store elements of different types in an array, you can use an Enum to define a custom data type that can hold multiple types. Enums will be explained in more detail in the "Enums and Pattern Matching" chapter.

#[derive(Copy, Drop)]
enum Data {
    Integer: u128,
    Felt: felt252,
    Tuple: (u32, u32),
}

fn main() {
    let mut messages: Array<Data> = array![];
    messages.append(Data::Integer(100));
    messages.append(Data::Felt('hello world'));
    messages.append(Data::Tuple((10, 30)));
}

Span

Span is a struct that represents a snapshot of an Array. It is designed to provide safe and controlled access to the elements of an array without modifying the original array. Span is particularly useful for ensuring data integrity and avoiding borrowing issues when passing arrays between functions or when performing read-only operations, as introduced in "References and Snapshots".

All methods provided by Array can also be used with Span, except for the append() method.

Turning an Array into Span

Bir Array'in Span'ini oluşturmak için span() yöntemini çağırın:

fn main() {
    let mut array: Array<u8> = ArrayTrait::new();
    array.span();
}