2014-11-18 7 views
7

Zum BeispielIst es möglich, in Rust eine mit Tausendertrennzeichen formatierte Zahl zu drucken?

println!("{}", 10_000_000); 

Ergebnisse in

10000000 

während ich es wie etwas aussehen zu formatieren möchte

10,000,000 

ich durch the fmt module documentation ging, aber es gibt nichts, dies zu decken besondere Situation. Ich dachte, so etwas wie dies funktionieren würde

println!("{:,i}", 10_000_000); 

aber es wirft einen Fehler

invalid format string: expected `}`, found `,` 
+2

Ich glaube nicht, dass das möglich ist, ohne jetzt benutzerdefinierten Code zu schreiben. – Dogbert

+0

Warum '10.000.000' und nicht' 1,00,00,000'? Wie würden Sie angeben, wie Sie Ziffern gruppieren? –

+0

@MatthieuM. Tausendertrennzeichen für Lesbarkeit. Die meisten, wenn nicht alle Sprachen haben diese Funktionalität, also habe ich mich gefragt, ob Rust das auch tut. – Caballero

Antwort

4

Es ist nicht, und es wird wahrscheinlich nicht sein.

Abhängig davon, wo Sie sich befinden, funktioniert das Tausendertrennzeichen möglicherweise auch wie 1,00,00,000 oder 1.000.000,000 oder eine andere Variante.

Lokalisierung ist nicht die Aufgabe der stdlib, plus format! wird meist zur Kompilierungszeit behandelt (obwohl fairerweise kann dies leicht in seinem Laufzeitabschnitt platziert werden), und Sie möchten nicht ein Gebietsschema hard-backen in das Programm.

+4

"Lokalisierung ist nicht die Aufgabe der stdlib" ist ernsthaft umstritten. Ich stimme sicherlich damit nicht überein, obwohl ich sagen werde, dass es noch nicht geeignet ist, es als Teil der Standardbibliotheken zu haben. –

+0

Das setzt voraus, dass Ihre Kulturgruppe Ziffern von 3 hat. – Aron

+1

Die Anzahl der Ziffern pro Gruppe und das Trennzeichen könnten angegeben werden. Z.B. Gruppen von 4, die durch _ getrennt sind, würden ein schönes Ausgabeformat für binäre oder hexadezimale Ziffern ergeben.(Soweit ich herausfand, verwendet Italienisch auch Gruppen von drei Ziffern, nicht das oben erwähnte unregelmäßige Format.) – starblue

0

eine benutzerdefinierte Funktion angeht, ich damit rumgespielt und hier sind einige Ideen:

use std::str; 

fn main() { 
    let i = 10_000_000i; 
    println!("{}", decimal_mark1(i.to_string())); 
    println!("{}", decimal_mark2(i.to_string())); 
    println!("{}", decimal_mark3(i.to_string())); 
} 

fn decimal_mark1(s: String) -> String { 
    let bytes: Vec<_> = s.bytes().rev().collect(); 
    let chunks: Vec<_> = bytes.chunks(3).map(|chunk| str::from_utf8(chunk).unwrap()).collect(); 
    let result: Vec<_> = chunks.connect(" ").bytes().rev().collect(); 
    String::from_utf8(result).unwrap() 
} 

fn decimal_mark2(s: String) -> String { 
    let mut result = String::with_capacity(s.len() + ((s.len() - 1)/3)); 
    let mut i = s.len(); 
    for c in s.chars() { 
     result.push(c); 
     i -= 1; 
     if i > 0 && i % 3 == 0 { 
      result.push(' '); 
     } 
    } 
    result 
} 

fn decimal_mark3(s: String) -> String { 
    let mut result = String::with_capacity(s.len() + ((s.len() - 1)/3)); 
    let first = s.len() % 3; 
    result.push_str(s.slice_to(first)); 
    for chunk in s.slice_from(first).as_bytes().chunks(3) { 
     if !result.is_empty() { 
      result.push(' '); 
     } 
     result.push_str(str::from_utf8(chunk).unwrap()); 
    } 
    result 
} 

Playpen: http://is.gd/UigzCf

Kommentare willkommen, keiner von ihnen fühlt sich wirklich schön.

0

Eine andere Problemumgehung für dieses Problem ist die Verwendung der saparator crate, die eine .separated_string()-Methode für Float-, Ganzzahl- und Größentypen implementiert. Hier ein Beispiel:

extern crate separator; 
use separator::Separatable; 

fn main() { 
    let x1: u16 = 12345; 
    let x2: u64 = 4242424242; 
    let x3: u64 = 232323232323; 
    println!("Unsigned ints:\n{:>20}\n{:>20}\n{:>20}\n", x1.separated_string(), x2.separated_string(), x3.separated_string()); 

    let x1: i16 = -12345; 
    let x2: i64 = -4242424242; 
    let x3: i64 = -232323232323; 
    println!("Signed ints:\n{:>20}\n{:>20}\n{:>20}\n", x1.separated_string(), x2.separated_string(), x3.separated_string()); 


    let x1: f32 = -424242.4242; 
    let x2: f64 = 23232323.2323; 
    println!("Floats:\n{:>20}\n{:>20}\n", x1.separated_string(), x2.separated_string()); 


    let x1: usize = 424242; 
    // let x2: isize = -2323232323; // Even though the docs say so, the traits seem not to be implemented for isize 
    println!("Size types:\n{:>20}\n", x1.separated_string());   
} 

Welche Sie die folgende Ausgabe gibt:

Unsigned ints: 
       12,345 
     4,242,424,242 
    232,323,232,323 

Signed ints: 
      -12,345 
     -4,242,424,242 
    -232,323,232,323 

Floats: 
     -424,242.44 
    23,232,323.2323 

Size types: 
      424,242 

Beachten Sie, dass Schwimmer wie diese Ausrichtung nicht einfach ist, da separated_string() einen String zurückgibt. Dies ist jedoch eine relativ schnelle Möglichkeit, getrennte Zahlen zu erhalten.

Verwandte Themen