Dizeleri nasıl birleştirebilirim?


201

Aşağıdaki tür birleşimlerini nasıl birleştirebilirim:

  • str ve str
  • String ve str
  • String ve String

14
O Not strve &strolan farklı tip ve zamanın% 99 oranında, yalnızca önemsemeliyiz &str. Aralarındaki farkları detaylandıran başka sorular da var.
Shepmaster

Yanıtlar:


235

Dizeleri birleştirdiğinizde, sonucu saklamak için bellek ayırmanız gerekir. Başlamak için en kolay Stringve &str:

fn main() {
    let mut owned_string: String = "hello ".to_owned();
    let borrowed_string: &str = "world";

    owned_string.push_str(borrowed_string);
    println!("{}", owned_string);
}

Burada, değişebileceğimiz, sahip olduğumuz bir dizemiz var. Bu, bellek tahsisini tekrar kullanmamıza olanak tanıdığından etkilidir. Orada için de benzer durum Stringve Stringgibi &String olarak indirgenmedikleri edilebilir&str .

fn main() {
    let mut owned_string: String = "hello ".to_owned();
    let another_owned_string: String = "world".to_owned();

    owned_string.push_str(&another_owned_string);
    println!("{}", owned_string);
}

Bundan sonra another_owned_string, dokunulmaz ( mutniteleyiciye dikkat edin ). Başka bir varyant var tüketirString ama değişken olmasını gerektirmez. This is an uygulanması Addözelliği bir alan Stringsol tarafta hem de bir &strsağ taraftaki olarak:

fn main() {
    let owned_string: String = "hello ".to_owned();
    let borrowed_string: &str = "world";

    let new_owned_string = owned_string + borrowed_string;
    println!("{}", new_owned_string);
}

Şu numaraya owned_stringsesli arama yapıldıktan sonra erişilemediğini unutmayın:+ .

Ya her ikisine de dokunmadan yeni bir dize üretmek isteseydik? En basit yol kullanmaktır format!:

fn main() {
    let borrowed_string: &str = "hello ";
    let another_borrowed_string: &str = "world";

    let together = format!("{}{}", borrowed_string, another_borrowed_string);
    println!("{}", together);
}

Her iki giriş değişkeninin değişmez olduğuna dikkat edin, bu yüzden bunlara dokunulmadığını biliyoruz. Herhangi bir kombinasyonu için aynı şeyi yapmak Stringistersek, Stringbiçimlendirilebilecek gerçeği de kullanabiliriz:

fn main() {
    let owned_string: String = "hello ".to_owned();
    let another_owned_string: String = "world".to_owned();

    let together = format!("{}{}", owned_string, another_owned_string);
    println!("{}", together);
}

Sen yok olması kullanmak format!gerçi. Sen olabilir tek bir dize klonlamak ve yeni bir dizeye diğer dize ekleyin:

fn main() {
    let owned_string: String = "hello ".to_owned();
    let borrowed_string: &str = "world";

    let together = owned_string.clone() + borrowed_string;
    println!("{}", together);
}

Not - yaptığım tüm tip özellikleri gereksizdir - derleyici burada oyundaki tüm türleri çıkarabilir. Bu sorunun o grupta popüler olmasını beklediğim için onları Rust için yeni olan insanlara açık olması için ekledim!


2
Add/ +Sembolü hakkında ne düşünüyorsun ? Coverstersen onu kaplayabilirsin.
bluss

Belki bu yeterince basittir, ancak anlamak, String ile Add için olası tür imzalarına bakmayı gerektirir.
bluss

Teşekkürler! & String'in bir & str olarak nasıl silinebileceği konusunda biraz daha derinlemesine gidebilir misiniz? Uygulanmasının hangi kısmı buna izin veriyor ve / veya bunu doco'da nerede söylüyor?
jsalter

1
@jsalter bu oldukça ayrı bir konu, bu yüzden başka bir üst düzey soru olarak iyi olabilir. Uygun dokümanlara bağlanmak için güncelledim (en azından alabildiğim kadar yakın ...)
Shepmaster

10
@ChrisMorgan Tutarsızlığın .to_owned()ve impl .to_string()uzmanlığı sayesinde yukarıdaki yorumdan bu yana düzeltildiğine dikkat edilmelidir . Her ikisi de a &str. İlgili taahhüt: github.com/rust-lang/rust/pull/32586/files
çad

49

Birden çok dizeyi, başka bir karakterle ayrılmış tek bir dizeye birleştirmek için birkaç yol vardır.

Gördüğüm en güzel joinyöntemi bir dizide kullanıyor:

fn main() {
    let a = "Hello";
    let b = "world";
    let result = [a, b].join("\n");

    print!("{}", result);
}

Kullanım durumunuza bağlı olarak daha fazla kontrol tercih edebilirsiniz:

fn main() {
    let a = "Hello";
    let b = "world";
    let result = format!("{}\n{}", a, b);

    print!("{}", result);
}

Gördüğüm birkaç manuel yol var, bazıları burada ve orada bir veya iki tahsis etmekten kaçınıyor. Okunabilirlik amacıyla yukarıdaki ikisinin yeterli olduğunu düşünüyorum.


Nerede joinbelgeleniyor? Bir Dizi ile bir String'in ortasında oturuyor gibi görünüyor. Dizi belgelerini araştırdım ve hemen kafam karıştı.
Duane J

3
@DuaneJ joinaslında bağlı özellik . Özellik kararsız olarak işaretlenir, ancak yöntemleri stabildir ve Prelude'a dahil edilir, böylece varsayılan olarak her yerde kullanılabilirler. Takım, bu özelliğin var olması gerekmediğinin farkında gibi görünüyor ve gelecekte bununla birlikte bir şeyler değişeceğini hayal ediyorum. SliceContactExt
Simon Whitehead

9

Bu concatyöntemi düşünüyorum ve +burada da belirtilmelidir:

assert_eq!(
  ("My".to_owned() + " " + "string"),
  ["My", " ", "string"].concat()
);

concat!makro da var ama sadece değişmez değerler için:

let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");

+mevcut bir cevapta zaten belirtilmiş . ( Bu bir uygulamasıdır Addalır özelliği bir Stringsol tarafı ve bir şekilde &strsağ tarafı olarak: )
Shepmaster

Doğru, mevcut cevap o kadar geniştir ki fark etmedim.
Ocak'ta

6

Dizeleri RUST içinde birleştirmenin basit yolları

Dizeleri birleştirmek için RUST'da çeşitli yöntemler vardır

İlk yöntem (Kullanma concat!()):

fn main() {
    println!("{}", concat!("a", "b"))
}

Yukarıdaki kodun çıktısı:

ab


İkinci yöntem ( push_str()ve +operatörü kullanarak ):

fn main() {
    let mut _a = "a".to_string();
    let _b = "b".to_string();
    let _c = "c".to_string();

    _a.push_str(&_b);
    
    println!("{}", _a);
 
    println!("{}", _a + &_b);
}

Yukarıdaki kodun çıktısı:

ab

ABC


Üçüncü yöntem ( Using format!()):

fn main() {
    let mut _a = "a".to_string();
    let _b = "b".to_string();
    let _c = format!("{}{}", _a, _b);
    
    println!("{}", _c);
}

Yukarıdaki kodun çıktısı:

ab

kontrol edin ve Rust oyun alanı ile deneme yapın


Bu cevap mevcut cevaplara yeni bir şey eklemez.
Shepmaster
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.