2016-12-17 15 views
4

我试图编译下面的程序:为什么在这里不使用std :: io?

use std::io; 

fn main() { 
    io::stdout().write(b"Please enter your name: "); 
    io::stdout().flush(); 
} 

不幸的是,编译器拒绝:

error: no method named `write` found for type `std::io::Stdout` in the current scope 
--> hello.rs:4:18 
    | 
4 |  io::stdout().write(b"Please enter your name: "); 
    |     ^^^^^ 
    | 
    = help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it: 
    = help: candidate #1: `use std::io::Write` 

我发现,我需要做的use std::io::{self, Write};use std::io;实际上是做什么,以及如何做(如果可能)我拉std::io定义的所有名称?另外,它会是一个不好的风格?

回答

11

use std::io;究竟做了什么呢?

它执行每个使用语句所做的操作:使所用路径的最后一部分直接可用(将其拉入当前名称空间)。这意味着您可以编写io,编译器知道您的意思是std::io

如何取出std::io中定义的所有名称?

use std::io::*;。这通常被称为glob-import

此外,它会是一个不好的风格?

是的,它会。通常你应该避免使用glob-imports。在某些情况下它们可以很方便,但在大多数情况下会造成很大的麻烦。例如,还有特征std::fmt::Write ...因此从fmtio导入所有内容都可能导致名称冲突。 Rust值隐含隐含性,所以避免了glob-imports。

但是,有一种模块通常与glob-import一起使用:preludes。事实上,甚至有一个std::io::prelude其重新出口重要的符号。有关更多信息,请参阅the documentation

+0

为什么我需要写入但不刷新?另外,不是那些标准输出/标准输入的方法? – d33tah

+1

'write()'和'flush()'是[Write'特征](https://doc.rust-lang.org/std/io/trait.Write.html)的方法。因此你只需要使用那个特质。 'Stdout'是一种实现* Write特性的类型。方法签名由特性给出,由类型本身实现。这是否澄清了这个问题? :) –

+0

所以'使用std :: io;'拉类型,但不是特征? – d33tah

相关问题