How do I disambiguate traits in Rust?
Solution 1:
You can call the trait method directly:
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"));
}
You can also choose to only import the trait in a smaller scope:
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"));
}
}
Note that if you choose to use a smaller scope, you can also use the write!
macro directly:
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");
}
}
In either case, you should handle the Result
return value.
See also:
- How to call a method when a trait and struct use the same name?
Solution 2:
You can specify an alias for 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"));
}
If you just want to call the traits method, you can even just bring them in scope:
use std::fmt::Write as _;
use std::io::Write as _;
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"));
}
Be careful, this solution works when different types implement different traits with the same name. If the same type implements different traits with the same name, you must use 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
}
}