2015-03-12 17 views
7

È considerato stile negativo dichiarare più istruzioni "uso" in Rust? Sono un programmatore C++ che ha recentemente iniziato a provare Rust. Una cosa che ho notato durante la revisione del codice Rust è che in molti programmi Rust ci saranno un sacco di istruzioni use nella parte superiore del programma. Venendo dal C++, è stato scoraggiato usare using namespace std specialmente quando si creano i file di intestazione, ma questo non sembra essere il caso della maggior parte dei programmi Rust che ho visto. Quindi quale dei seguenti esempi banali è considerato uno stile di programmazione Rust migliore? Cambia se stai facendo un programma binario rispetto a un modulo? E perché?Rust "use" vs. C++ "utilizzando namespace"

use std::sync::Arc; 
use std::sync::Mutex; 
use std::thread::Thread; 
use std::rand::random; 

fn main() { 
    let mut vec: Vec<char> = (0u8..10).map(|i| i as char).collect(); 

    let mut data = Arc::new(Mutex::new(vec)); 
    for i in 1usize..10 { 
     let data = data.clone(); 
     let thread = Thread::spawn(move || { 
      let mut data = match data.lock() { 
       Ok(guard) => guard, 
       Err(e)  => panic!("{}, was poisoned", e) 
      }; 
      data.push(random::<char>()); 
     }); 
    } 
} 

O questo ...

fn main() { 
    let mut vec: Vec<char> = (0u8..10).map(|i| i as char).collect(); 

    let mut data = std::sync::Arc::new(
          std::sync::Mutex::new(vec) 
             ); 
    for i in 1usize..10 { 
     let data = data.clone(); 
     let thread = std::thread::Thread::spawn(move || { 
      let mut data = match data.lock() { 
       Ok(guard) => guard, 
       Err(e)  => panic!("{}, was poisoned", e) 
      }; 
      data.push(std::rand::random::<char>()); 
     }); 
    } 
} 

risposta

13

Siete probabilmente confusi con i nomi simile guardato (use e using namespace). In realtà sono molto diversi nella semantica.

using namespace in C++ include l'intero contenuto di un namespace nel campo di applicazione corrente, in modo, ad esempio, è possibile utilizzare cout invece di std::cout:

using namespace std; 

cout << "Hello!\n"; 

use a Rust, tuttavia, include solo il nome specificato , in modo da avere ancora a qualificarsi quale elemento in realtà si sta riferendo a:

use std::mem; 
use std::fmt::Debug; 

fn do_something<T: Debug>(t: T) { ... } 

fn main() { 
    let (mut x, mut y) = ...; 
    mem::swap(&mut x, &mut y); 
} 

si noti come Debug viene usato senza qualificazione, ma swap richiede ancora un qualificatore di modulo, quindi use in Rust è più simile a using (senza namespace) in C++. Poiché use è molto specifico in ciò che importa, è considerato un buon stile usarlo quasi sempre, quindi il tuo primo esempio è quello idiomatico.

In realtà, è più simile a using namespace importazioni glob a Rust:

use std::*; 

E glob importazioni in effetti sono un po 'scoraggiati. Tuttavia, le convenzioni di strutturazione di Rust sono più flessibili di quelle utilizzate da C++ (in particolare, nella libreria std), quindi use std::* non fornirà l'intera libreria standard, ma solo i moduli di livello superiore. Le importazioni Glob sono anche utili in un paio di altre situazioni, ad es. quando si riesaminano i nomi da un altro modulo o si assemblano tutti i tratti di estensione della libreria in un modulo.

E no, le convenzioni non cambiano a prescindere se si sta scrivendo una libreria o un eseguibile. Rust non ha nulla di simile alle intestazioni di C/C++ con inclusioni letterali, quindi ogni unità di compilazione è completamente indipendente e può avere qualsiasi importazione che ti piace - non influenzerà i suoi utenti (a meno che questi non siano pub use, ovviamente).

+5

Si noti che C++ ha anche il nome singolo 'using', ad es. 'usando std :: cout;' funziona bene in C++. Quindi no, 'using' non è una dichiarazione di importazione globale. "using namespace', d'altra parte, è, ed è abbastanza autoesplicativo nei suoi effetti. – rubenvb

+0

Ah, mi dispiace, hai ragione. Non lavoro molto con il C++, quindi potrei sicuramente sbagliarmi. –

0

using System; in C# è del tutto normale e in Java, ancora non hanno bisogno di scrivere import java.lang.*; in quanto è già importata per impostazione predefinita. E non vedo alcun difetto nello scrivere più affermazioni - se hai bisogno di chiamare qualcosa con lo stesso nome, puoi sempre chiamare gli identificatori con il loro nome completo, come hai fatto nel tuo secondo esempio di codice.

P.S .: Ci dispiace per la scrittura di un parere guidato risposta ^^

Problemi correlati