2016-04-29 14 views
2

Ich möchte nur ein Leerzeichen getrennt String der Argumentvariablen von std::env::args() erhalten, die ich die fold Funktion wie diese zu schaffen habe mit:Was ist ein idiomatischer Weg, um einen Iterator getrennt durch Leerzeichen in Rust zu drucken?

std::env::args() 
    .fold("".to_string(), |accum, s| accum + &s + " ") 

jedoch diese am Ende einen zusätzlichen Raum schafft, die unerwünscht ist. Ich versuchte, die truncate Funktion, aber truncate keine String zurückkehrt, ändert nur die bestehenden String, und auch dies würde die Schaffung eines Zwischen Bindung erfordern, um die String ‚s len() Aufruf zu verwenden, um festzulegen, wie lange die abgeschnittenen String sein sollte (die selbst würde eine Zwischen Bindung aufgrund Rust aktuellen lexikalischer Entlehnung Regeln erfordern glaube ich!)

+0

Ich glaube, wenn Sie den Lambda-Ausdruck auf 'accum +" ändern "+ & s", der nachgestellte Raum wird verschwinden. – Ferruccio

+0

@Ferruccio Dies führt nur zu einem führenden Leerzeichen, ich habe es nur so gemacht, weil ein schließendes Leerzeichen oft unsichtbar ist, während ein führendes Leerzeichen in der Formatierung zu sehen ist. Ich hätte angeben sollen, führende und nachstehende Leerzeichen sind jedoch unerwünscht. –

+2

Es gibt eine ['intersperse '] (https://bluss.github.io/rust-itertools/doc/itertools/trait.Itertools.html#method.intersperse) -Methode in' itertools', wenn Sie eine hinzufügen möchten Abhängigkeit. Ich denke nicht, dass es einen einfachen Weg gibt, dies mit 'std' zu tun. – Dogbert

Antwort

2

Was Druck alle Befehlszeilenargumente in Rust ein idiomatischen Weg ist?

fn main() { 
    let mut args = std::env::args(); 

    if let Some(arg) = args.next() { 
     print!("{}", arg); 

     for arg in args { 
      print!(" {}", arg); 
     } 
    } 
} 

Oder besser mit itertools' format:

extern crate itertools; 

use itertools::Itertools; 

fn main() { 
    println!("{}", std::env::args().format(" ")); 
} 

Ich möchte nur ein Leerzeichen getrennt String

fn args() -> String { 
    let mut result = String::new(); 
    let mut args = std::env::args(); 

    if let Some(arg) = args.next() { 
     result.push_str(&arg); 

     for arg in args { 
      result.push(' '); 
      result.push_str(&arg); 
     } 
    } 

    result 
} 

fn main() { 
    println!("{}", args()); 
} 

Oder

fn args() -> String { 
    let mut result = std::env::args().fold(String::new(), |s, arg| s + &arg + " "); 
    let len = result.len() - 1; 
    result.truncate(len); 
    result 
} 

fn main() { 
    println!("{}", args()); 
} 

Wenn Sie itertools verwenden, join ist nützlich:

extern crate itertools; 

use itertools::Itertools; 

fn args() -> String { 
    std::env::args().join(" ") 
} 

fn main() { 
    println!("{}", args()); 
} 

In anderen Fällen möchten Sie vielleicht intersperse verwenden:

extern crate itertools; 

use itertools::Itertools; 

fn args() -> String { 
    std::env::args().intersperse(" ".to_string()).fold(String::new(), |s, a| s + &a) 
} 

fn main() { 
    println!("{}", args()); 
} 

Hinweis: Das ist nicht extrem effizient Eine String wird für jede Iteration geklont. Hier

+3

Wenn Sie die 'for' -Schleife in das' if let' setzen, müssen Sie 'fuse' nicht verwenden. – malbarbo

+2

Mit 'itertools' können Sie einfach' std :: env :: args(). Join ("") '(Danke an OP und @bluss für den Tipp in den Fragekommentaren). – Dogbert

0

ist eine Alternative für

Ich will nur ein Raum String der Argumentvariablen getrennt erhalten von std::env::args()

fn args_string() -> String { 
    let mut out = String::new(); 
    let mut sep = ""; 
    for arg in std::env::args() { 
     out.push_str(sep); 
     out.push_str(&*arg); 
     sep = " "; 
    } 
    out 
} 

pub fn main() { 
    println!("{}", args_string()); 
} 
Verwandte Themen