はじめに
こんにちは。細々とプログラミングをしているsotanengelです。
この記事は以下の記事の連載です。
他の連載記事 (詳細)
- Day 1:型システムを使ってデータ構造を再現しよう
- Day 2:型システムを用いて共通の挙動を表現しよう
- Day 3:OptionとResultに対してはmatchを用いずに変換しよう
- Day 4:標準のErrorを使おう
- Day 5:型変換を理解しよう
- Day 6:newtypeパターンを活用しよう
- Day 7:複雑な型にはビルダを使おう
- Day 8:明示的なループの代わりにイテレータ変換を使用することを検討しよう
- Day 9:標準トレイトに習熟しよう
- Day 10:RIIパターンにはDropトレイトを実装しよう
- Day 11:ジェネリクスとトレイトオブジェクトのトレードオフを理解しよう
- Day 12:デフォルト実装を用いて、実装しなければならないトレイトメソッドを最小限にしよう
- Day 13:Don't panic
- Day 14:リフレクションを避けよう
- Day 15:可視範囲を最小化しよう
- Day 16:ワイルドカードインポートを避けよう
- Day 17:パブリックインターフェースのドキュメントを書こう
- Day 18:分別を持ってマクロを使おう
- Day 19:Clippyに耳を傾けよう
- Day 20:ユニットテスト以上のものを書こう
また本記事はEffective Rust(David Drysdale (著), 中田 秀基 (翻訳))を参考に作成されております。とてもいい書籍ですので興味を持った方は、ぜひ読んでみてください!
今日の内容
概要
Rustではワイルドカード(*)を使って一連のアイテムを取り込むことができます。
ただしワイルドカードを使ったインポートには問題点もあります。
ワイルドカードインポートを避けて実装しよう
問(リンク)
同じトレイト名が実装されているため、名前が衝突してしまっています。
明示的にインポートすることで問題を解消しましょう。
コード (詳細)
mod module_a {
pub trait MyTrait {
fn foo(&self);
}
}
mod module_b {
#[allow(dead_code)]
pub trait MyTrait {
fn bar(&self);
}
pub trait AnotherTrait {
fn baz(&self);
}
}
// TODO: ワイルドカードを使ってしまったため、トレイト名が衝突してしまっています。
// 明示的にインポートをすることで問題を解消してください。
use module_a::*;
use module_b::*;
struct MyStruct;
impl MyTrait for MyStruct {
fn foo(&self) {
println!("Foo from module_a");
}
}
// module_b の AnotherTrait を MyStruct に対して実装
impl AnotherTrait for MyStruct {
fn baz(&self) {
println!("Baz from module_b");
}
}
fn main() {
let s = MyStruct;
s.foo();
s.baz();
}
解答(リンク)
コード参照。
書籍上では以下のような場合に問題が起きるとされているため、ワイルドカードは避けた方がいいと思われる。
- インポートしているクレートやモジュールが更新され、ローカルで使用している名前と合致してしまう
コード (詳細)
mod module_a {
pub trait MyTrait {
fn foo(&self);
}
}
mod module_b {
#[allow(dead_code)]
pub trait MyTrait {
fn bar(&self);
}
pub trait AnotherTrait {
fn baz(&self);
}
}
// ワイルドカードを使わずに指定する
use module_a::MyTrait;
use module_b::AnotherTrait;
struct MyStruct;
impl MyTrait for MyStruct {
fn foo(&self) {
println!("Foo from module_a");
}
}
// module_b の AnotherTrait を MyStruct に対して実装
impl AnotherTrait for MyStruct {
fn baz(&self) {
println!("Baz from module_b");
}
}
fn main() {
let s = MyStruct;
s.foo();
s.baz();
}
さいごに
もしも本リポジトリで不備などあれば、リポジトリのissueやPRなどでご指摘いただければと思います。