以下のようになるのはなぜでしょうか。 (playground)
rust
1fn foo<T: std::io::Write>(mut x: T) { 2 // OK 3 x.write_all(b"hello\n").unwrap(); 4 T::write_all(&mut x, b"Hello").unwrap(); 5} 6 7fn bar_impl<T: std::io::Write>(x: T) -> impl std::io::Write { 8 x 9} 10 11fn bar_dyn<T: std::io::Write + 'static>(x: T) -> Box<dyn std::io::Write> { 12 Box::new(x) 13} 14 15fn main() { 16 foo(std::io::stdout()); 17 18 // OK 19 bar_dyn(std::io::stdout()).write_all(b"world").unwrap(); 20 21 // E0599: no method named `write_all` found for 22 // type `impl std::io::Write` in the current scope 23 bar_impl(std::io::stdout()).write_all(b"hello").unwrap(); 24}
Rust では、トレイトに定義されているメソッドを (Fully Qualified Path を使わず) 呼び出す際は基本的にそのトレイトが use によってスコープに持ち込まれている必要があります。ところがこれにはいくつか例外があるように見えます。上の例では、境界にトレイトが指定されているような型の変数とトレイトオブジェクト Box<dyn Trait>
については use
せずに使えることが示されています。なぜ impl Trait
についてはこうならないのでしょうか。
追記
トレイト境界が明記してあっても単純 (?) なものでないとダメなようです。
rust
1// Error 2fn foo<'a, T, F: FnOnce(&'a mut T) -> &'a mut T>(x: &'a mut T, f: F) 3where 4 &'a mut T: std::io::Read, 5{ 6 let _ = f(x).bytes(); 7} 8 9// OK 10fn bar<'a, T, U, F: FnOnce(&'a mut T) -> U>(x: &'a mut T, f: F) 11where 12 U: std::io::Read, 13{ 14 let _ = f(x).bytes(); 15}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/09 18:14
2019/07/10 14:29
2019/07/10 15:35