Rust giriş kılavuzu: satır üstüne satır | CSDN blog seçimi

Yazar | Jackyzhe

Editör | Tu Min

Rust'un çukurlarını uzun zamandır kazmadım Bugün, özenle düzenlenmiş çukurlar kazacağım. Evet, bazı veri toplama türlerini tanıtmaktır. "Satır ardına satır" başlığı çok kültürel görünüyor mu?

Rust Guide to the Pit: General Routines'de (https://blog.csdn.net/K_Ohaha/article/details/102481562), bazı temel veri türlerini tanıttık. Hepsi yığın içinde saklanıyor. Bugün tanıtmaya odaklanacağız Üç veri türü: dizi, vektör ve karma harita.

Dize

Önceki çalışmada String türü ile daha fazla temas kurduk, ancak onu ayrıntılı olarak tanıtmadık. Bir programlama temeline sahip bazı öğrenciler, String tipini öğrenmeyi küçümseyebilir, sonuçta, tüm programlama dillerinde en yaygın kullanılan tip olduğu ve herkesin buna aşinalığının olduğu söylenebilir. Bu tür psikolojiye sahip öğrenciler için onlara şunu söylemek istiyorum: Başlangıçta da aynı şeyi düşündüm ve derleyici tarafından dövülene kadar geri dönüp String türünü ciddi bir şekilde incelemeye karar verdim.

Pas dizeleri aşağıdaki türlere ayrılır:

  • str: sabit uzunlukta bir dize

  • Dize: Büyüyebilen bir dize

  • CStr: C tarafından ayrılan ve Rust tarafından ödünç alınan, genellikle C diliyle etkileşimde kullanılan bir dizeyi temsil eder.

  • CString: Rust tarafından ayrılmış bir dizeyi temsil eder ve C diline geçirilebilir

  • OsStr: esas olarak Windows ile uyumluluk için işletim sistemiyle ilgili bir dizeyi temsil eder

  • OsString: OsStr'in değişken bir versiyonu

  • Yol: yolu belirtir

  • PathBuf: Path'in değişken versiyonu

Bu yazıda ilk ikisine odaklanıyoruz çünkü bunlar geliştirme sürecinde en sık kullanılanlar ve aynı zamanda karıştırılmaları da kolay. Str için ortak referans tipimiz str'dir. Rust Guide to the Pit: Core Concepts'i okuduysanız, referans türleri ve sahiplik kavramlarını zaten anladığınıza inanıyorum. Başka bir deyişle, String türünün Sahipliği vardır, ancak str yoktur.

Rust'ta String aslında Vec'dir < u8 > , Vec vektör toplama anahtar kelimesi, daha sonra tanıtacağız. Dize türü üç bölümden oluşur, yani: yığındaki bayt dizisine bir işaretçi, yığındaki bayt dizisinin uzunluğunu ve yığın tarafından tahsis edilen kapasiteyi kaydeder. Belki bir kod parçasıyla daha derin bir anlayışa sahipsiniz.

fn main { let mut a = String :: from ("foo"); println! ("{: p}", a.as_ptr); println! ("{: p}", a); assert_eq! (a.len, 3); a. rezerv (10); assert_eq! (a. kapasite, 13); }

Bu kodda, a.as_ptr ile elde edilen göstericinin a ile elde edilen gösterici ile aynı olmadığını görebiliriz.

Burada as_ptr ile elde edilen göstericinin öbek içindeki bayt dizisinin gösterici adresi olduğunu ve a'nın adresi yığın üzerindeki dizge değişkeninin işaretçi adresidir. Ayrıca, uzunluk ve kapasite yöntemleriyle elde edilen uzunluk, karakter sayısı değil, bayt sayısıdır. Burada Çince karakterlerin uzunluğunu kendiniz deneyebilirsiniz.

Tellerin temel kavramlarından bahsettikten sonra, Rust dizeleri hakkında genel bir anlayışa sahip olduğunuza inanıyorum. Ardından, CRUD karakter dizisi yöntemine bir göz atalım.

Dize oluştur

Söyleyecek fazla bir şey yok, önce dizeleri oluşturmanın çeşitli yöntemlerini gösterelim.

fn main { let string: String = String :: new; let string: String = String :: from ("merhaba pas"); let string: String = String :: with_capacity (10); let str: 'statik str = "Jackey"; let dizge: String = str.to_owned; let dizge: String = str.to_string; }

İlk ikisi daha yaygın olarak kullanılır ve aşağıdaki yöntemler aşağıda tanıtılmıştır. with_capacity boş bir dizge oluşturmaktır, parametre öbek içinde ayrılan bayt sayısını gösterir. to_owned ve to_string, str türünün String türüne nasıl dönüştürüleceğini gösterir.

Dizeyi değiştir

Rust ayrıca dizeleri değiştirmek için bir dize eklemek, iki dizeyi birleştirmek, bir dizeyi güncellemek gibi birçok yaygın yola sahiptir. Aşağıdaki kod, dizeyi değiştirmenin bazı yollarını gösterir.

fn main { let mut merhaba = String :: from ("Merhaba,"); merhaba.push ('J'); // tek bir karakter ekleyin hello.push_str ("ackey!"); // Dize ekle println! ("push: {}", merhaba); merhaba.extend (.iter); // Birden fazla karakter ekleyin, parametre yineleyicidir merhaba.extend ("isim" .chars); println! ("extension: {}", merhaba); merhaba.insert (0, 'h'); // Push'a benzer şekilde, ekleme konumunu belirtebilirsiniz merhaba.insert (1, 'a'); merhaba.insert (2, '!'); merhaba.insert_str (0, "Haha"); println! ("insert: {}", merhaba); let left = "Merhaba," .to_string; let right = "Dünya" .to_string; sonuç = sol + println! ("+: {}", sonuç); // Dizeyi bağlamak için + kullanırken, ikincisi bir referans olmalıdır let mut message = "rust" .to_string; // Bir dizeyi bağlamak için + = kullanırken, dizge değişken olarak tanımlanmalıdır mesaj + = "!"; println! ("+ =: {}", mesaj); let s = String :: from ("foobar"); let s: String = s .chars .enumerate .map (| (_i, c) | {c.to_uppercase.to_string}) .toplamak; println! ("karakterleri güncelle: {}", s); let s1 = String :: from ("merhaba"); let s2 = String :: from ("pas"); let s3 = biçim! ("{} - {}", s1, s2); println! ("biçim: {}", s3); }

Yukarıdaki koda bazı ek açıklamalar yapıyoruz.

İtme, eklemeye benzerdir. _Str içeren yöntem bir dizge alır, aksi takdirde yalnızca tek bir karakter alabilir. Ekle, eklenecek konumu belirleyebilirken, itme yalnızca dizenin sonuna ekleyebilir.

Dizeleri bağlamak için "+" kullanılırken, ilk parametre Dize türüdür ve ikinci parametrenin başvuru türü str olması gerekir. Bu, add yöntemini çağırmaya benzer ve tanımı şu şekildedir:

Bu nedenle, ilk parametrenin sahipliği işleve aktarılır ve ardından dönüş sonucundan geçirilir. Başka bir deyişle, + operatörünü kullandıktan sonra solun hiçbir sahipliği kalmaz.

Dize araması

Rust'ta bir dize, konumuna bağlı olarak belirli bir karakteri alamaz. Yani aşağıdaki kod derlenmemiştir.

let s1 = String :: from ("merhaba"); let h = s1;

Çünkü Rust, bu 0'ın ilk bayta atıfta bulunduğunu düşünecek ve Rust dizesindeki karakterlerin birden fazla bayt alabileceğini (kodda Çince karakterlerle denemenizi istediğimi hatırlıyor musunuz?) Yani, sadece isterseniz Bir bayt elde etmek için derleyici, bayta veya karaktere karşılık gelen değeri gerçekten almak isteyip istemediğinizi bilmez.

Dizelerle uğraşırken genellikle aşağıdaki yöntemlere sahibiz:

fn main { merhaba = ""; let s = println! ("{}", s); let chars = merhaba.chars; c in chars { println! ("{}", c); } let bayt = merhaba.bayt; bayt cinsinden bayt için { println! ("{}", bayt); } let get = merhaba.get (0..1); let mut s = String :: from ("merhaba"); let get_mut = s.get_mut (3..5); let mesaj = String :: from ("merhaba-dünya"); let (sol, sağ) = message.split_at (6); println! ("sol: {}, sağ: {}", sol, sağ); }

Genellikle karakter dilimlemeyi kullanın, Chars yineleyicisini almak için chars yöntemini de kullanabilirsiniz ve ardından her karakter ayrı ayrı işlenebilir. Ek olarak, get veya get_mut yöntemini kullanmak da dizin aralığını alabilir ve belirtilen dize dilimini döndürebilir. Dönüş sonucu Seçenek türündedir, çünkü belirtilen dizin dönüşü tam bir karakter döndüremiyorsa, Rust Yok döndürür. Burada da kullanılabilir dır-dir Bir konumun yasa dışı sınır olup olmadığını belirlemek için _char_boundary yöntemi.

Son olarak, dizeyi bölmek için split_at veya split_at_mut da kullanabilirsiniz. Bu, bölünmenin konumunun tam olarak karakter sınır konumu olmasını gerektirir, değilse program çökecektir.

Dizeyi sil

Rust'un standart kitaplığı dizeleri silmek için bazı yöntemler sağlar, hadi bazılarını gösterelim:

fn main { let mut merhaba = String :: from ("merhaba"); merhaba.remove (3); println! ("kaldır: {}", merhaba); merhaba.pop; println! ("pop: {}", merhaba); merhaba.truncate (1); println! ("truncate: {}", merhaba); merhaba.clear; println! ("clear: {}", merhaba); }

Sonuçlar şekilde gösterilmektedir:

Remove yöntemi, bir dizedeki bir karakteri silmek için kullanılır.Aldığı parametre, karakterin başlangıç konumudur.Bir karakterin başlangıç konumu değilse, program çökecektir.

Pop yöntemi dizenin sonundaki karakterleri açacaktır, truncate yöntemi dizenin belirtilen uzunluğunu kesmektir ve clear yöntemi dizeyi temizlemektir.

Bu noktada, Rust ve CRUD'da dizelerin temel kavramlarını zaten tanıttık ve sonra başka bir koleksiyon türü olan Vector'e bakacağız.

Vektör

Vektör, aynı veri türündeki birden çok veriyi depolamak için kullanılan bir veri türüdür. Anahtar kelimesi Vec < T > . Vektörlerin CRUD'ına bir göz atalım.

Vektör oluştur

fn main { let v1: Vec < i32 > = Vec :: yeni; let v2 = vec !; }

Yukarıdaki kod, bir vektör oluşturmanın iki yolunu gösterir: Birincisi, boş bir vektör oluşturmak için yeni işlevi kullanmaktır.Hiçbir öğe eklenmediğinden, depolama öğesinin türü açıkça belirtilmelidir. İkincisi, başlangıç değerleriyle bir vektör kümesi oluşturmaktır, doğrudan vec kullanıyoruz! Makro ve ardından başlangıç değerini belirtin.Vektördeki öğelerin veri türünü belirtmeye gerek yoktur, çünkü derleyici bunu kendi başına çıkarabilir.

Vektörü güncelle

fn main { let mut v = Vec :: new; v.push (1); v.push (2); }

Boş bir vektör oluşturduktan sonra, eleman eklemek istersek, elemanları sonuna eklemek için doğrudan push yöntemini kullanabiliriz.

Vektörü sil

fn main { let mut v = Vec :: new; v.push (1); v.push (2); v.push (3); v.pop; i in v {için println! ("{}", i); } }

Tek bir elemanı silmek için pop yöntemini kullanabilirsiniz.Tüm vektörü silmek için, sahipliği başarısız olana kadar diğer yapılar gibi sadece tüm vektörü silebilirsiniz.

Vektör öğelerini okuyun

fn main { let v = vec !; üçüncü olalım: i32 = println! ("Üçüncü öğe dır-dir {} ", üçüncü); maç v.get (2) { Bazıları (üçüncü) = > println! ("Üçüncü öğe dır-dir {} ", üçüncü), Yok = > println! ("Orada dır-dir üçüncü öğe yok. "), } let v = vec !; i in v {için println! ("{}", i); } }

Belirtilen tek bir öğeyi okumanız gerektiğinde, iki yöntem vardır, biri kullanmak, diğeri ise get yöntemini kullanmaktır. İki yöntem arasındaki fark şudur: Birincisi öğe türünü döndürürken get, Seçenek türünü döndürür. Belirttiğiniz konum aralık dışındaysa, program ilk yöntemi kullanırken doğrudan çökecek ve ikinci yöntemi kullanırken Hiçbiri döndürülecektir.

Ek olarak, öğeleri çapraz vektörler şeklinde de okuyabilirsiniz. Farklı veri türlerini depolamak istiyorsanız, numaralandırılmış türleri kullanabiliriz.

fn main { enum SpreadsheetCell { Int (i32), Kayan (f64), Metin dizesi), } let satır = vec! ; }

HashMap

HashMap, KV yapısının verilerini depolar, her Anahtar aynı tipte olmalı ve her Değer aynı tipte olmalıdır. HashMap, üç koleksiyon türünden en az kullanılanı olduğundan, kullanımdan önce manuel olarak tanıtılması gerekir.

std :: collections :: HashMap kullanın;

HashMap Oluştur

Öncelikle, yeni bir Karma Haritanın nasıl oluşturulacağına ve elemanların nasıl ekleneceğine bakalım.

std :: collections :: HashMap kullanın; fn main { let field_name = String :: from ("Favori renk"); let field_value = String :: from ("Mavi"); let mut map = HashMap :: new; map.insert (alan_adı, alan_değer); }

Ekleme yöntemini kullanırken, hem alan_adı hem de alan_değerinin sahipliğini kaybettiğini unutmayın. Tekrar nasıl kullanılır? Onu sadece Hash Haritasından çıkarabiliriz.

Karma Harita verilerine erişin

std :: collections :: HashMap kullanın; fn main { let field_name = String :: from ("Favori renk"); let field_value = String :: from ("Mavi"); let mut map = HashMap :: new; map.insert (alan_adı, alan_değer); let favori = String :: from ("Favori renk"); let color = map.get (favori); renk eşleme { Bazıları (x) = > println! ("{}", x), Yok = > println! ("Yok"), } }

Gördüğünüz gibi, belirtilen Anahtarın değerini almak için get kullanabiliriz.Get yöntemi Seçenek türünü döndürür, Belirtilen bir Değer yoksa, Yok döndürür. Ek olarak, Karma Haritadan geçmek için bir for döngüsü de kullanabilirsiniz.

std :: collections :: HashMap kullanın; fn main { let mut puanları = HashMap :: new; score.insert (String :: from ("Mavi"), 10); score.insert (String :: from ("Yellow"), 50); puanlarda (anahtar, değer) için { println! ("{}: {}", anahtar, değer); } }

Karma Haritasını Güncelle

Aynı Anahtara bir değer eklediğimizde eski değerin üzerine yazılacaktır. Yalnızca Anahtar olmadığında eklemek istiyorsanız, girişi kullanabilirsiniz.

std :: collections :: HashMap kullanın; fn main { let mut puanları = HashMap :: new; score.insert (String :: from ("Mavi"), 10); score.entry (String :: from ("Yellow")). or_insert (50); score.entry (String :: from ("Blue")). or_insert (50); println! ("{:?}", puanlar); }

sonuç olarak

Bugün sizi üç çukur, dize, vektör ve karma harita kazmaya götürdüm ve her veri türünün CRUD'unu tanıttım. Dizeye giriş, en yaygın kullanılan veri türlerinden biri olduğu için çok yer kaplar. Tabii ki, bu bölümde hala birçok ilgili bilgi var.Herkes öğrenmeye ve benimle iletişim kurmaya hoş geldiniz.

Feragatname: Bu makale, CSDN blogger "Jackyzhe" nin orijinal makalesidir.

Python için en iyi 30 uygulama, ipucu ve püf noktası
önceki
Her genç geliştiricinin bilmesi gereken altı şey
Sonraki
Guangxi, taşkın mevsiminde dağ demiryollarının güvenliğini sağlamak için demiryolu ağlarının bakımı için "uçak gemisi" gönderiyor
Wuxi Yuantouzhu kiraz çiçekleri en iyi izleme dönemine girer, turistler "Romantik Tarih" e gider
Yemek önerisi: lezzetli ananaslı kruvasan ekmeği
Geri dönüşüm kutusu kurtarma ücreti var mı? Dosyaları 1 dakika içinde bulmayı öğretmek
Eyalet Büyük Veri Bürosu "ikili kayıt" çalışmasını derinleştiriyor ve "yardım topluluğu salgını önleme" gönüllü faaliyetlerini başlatıyor
Baidu Industry Recovery Big Data: İşe alım arama popülaritesi% 165 arttı
Büyük ve küçük boncuklar yeşim tabağına düşer Loudinin kültür endüstrisinin gelişimini teşvik etmek için "Beş Ünlü Projesi" nin özeti
Savaş Salgını Günlüğü: "Ağır sorumluluğu üstlenmek ve karanlık gecede lambayı tutmak dile"
Zhong Nanshanın ekibi Xu Yuanda: yedi veya sekiz kritik hasta ile en fazla bir konsültasyon
Dongguan Belediye Halk Hastanesi, uzmanlara ücretsiz danışmanlık hizmeti veren "Yeni Koroner Pnömoni Takip Kliniğini" açtı
5 yılda 2 milyondan fazla insanın akını! Guangzhou, önümüzdeki 15 yıl içinde 4,7 milyon kişi ekleyebilir
Chen He, ikinci çocuğun bir kızı olduğunu duyuran bir video paylaştı
To Top