2017-07-06 51 views
4

我想使用兩種不同類型的對象write_fmt方法:使用Write我如何消除Rust中的特徵?

use std::fmt::Write; 
use std::io::Write; 

fn main() { 
    let mut a = String::new(); 
    let mut b = std::fs::File::create("test").unwrap(); 

    a.write_fmt(format_args!("hello")); 
    b.write_fmt(format_args!("hello")); 
} 

我得到一個錯誤,因爲它們都命名爲相同的:

error[E0252]: a trait named `Write` has already been imported in this module 
--> src/main.rs:8:5 
    | 
7 | use std::fmt::Write; 
    |  --------------- previous import of `Write` here 
8 | use std::io::Write; 
    |  ^^^^^^^^^^^^^^ `Write` already imported 
     a.write_fmt(format_args!("hello")); 
     b.write_fmt(format_args!("hello")); 

或者我得到一個錯誤說的特點是不可用:

error[E0599]: no method named `write_fmt` found for type `std::fs::File` in the current scope 
    --> src/main.rs:76:4 
    | 
76 | b.write_fmt(format_args!("hello")); 
    |  ^^^^^^^^^ 
    | 
    = 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;` 

回答

8

可以直接調用性狀方法:

fn main() { 
    let mut a = String::new(); 
    let mut b = std::fs::File::create("test").unwrap(); 

    std::fmt::Write::write_fmt(&mut a, format_args!("hello")); 
    std::io::Write::write_fmt(&mut b, format_args!("hello")); 
} 

您也可以選擇只導入特徵在一個較小的範圍:

fn main() { 
    let mut a = String::new(); 
    let mut b = std::fs::File::create("test").unwrap(); 

    { 
     use std::fmt::Write; 
     a.write_fmt(format_args!("hello")); 
    } 

    { 
     use std::io::Write; 
     b.write_fmt(format_args!("hello")); 
    } 
} 

請注意,如果您選擇使用一個較小的範圍內,也可以直接使用write!宏:

fn main() { 
    let mut a = String::new(); 
    let mut b = std::fs::File::create("test").unwrap(); 

    { 
     use std::fmt::Write; 
     write!(a, "hello"); 
    } 

    { 
     use std::io::Write; 
     write!(b, "hello"); 
    } 
} 

在這兩種情況下,你應該處理Result返回值。

參見:

+0

這工作,謝謝,你! – ashleysmithgpu

5

可以爲use指定別名:

use std::fmt::Write as FmtWrite; 
use std::io::Write; 

fn main() { 
    let mut a = String::new(); 
    let mut b = std::fs::File::create("test").unwrap(); 

    a.write_fmt(format_args!("hello")); 
    b.write_fmt(format_args!("hello")); 
} 

要小心,當不同類型實施不同的特質此解決方案有效同名。如果同一類型,具有相同的名稱實現不同的特質,你必須使用Shepmaster's answer

mod foo { 
    pub trait Trait { 
     fn do_something(&self) {} 
    } 
} 

mod bar { 
    pub trait Trait { 
     fn do_something(&self) {} 
    } 
} 

pub struct Concrete {} 
impl foo::Trait for Concrete {} 
impl bar::Trait for Concrete {} 

fn main() { 
    let x = Concrete {}; 

    { 
     use foo::Trait; // use limited to scope 

     x.do_something(); // call foo::Trait::do_something 
    } 
    {  
     foo::Trait::do_something(&x); // complete path to disambiguate 
     bar::Trait::do_something(&x); // complete path to disambiguate 
    } 
    { 
     use foo::Trait as FooTrait; 
     use bar::Trait; 

     x.do_something(&x); // ERROR: multiple applicable items in scope 
    } 
} 
相關問題