アペフチ

実装されているはずのメソッドが呼べなくてハマった

Rust勉強中です。

勉強中にありがちな、「分かってみればもう間違えないけど、最初は何が問題なのか全然分からない」というタイプのハマり方をしたので記録として書きます。

EPUBファイルの中身を調べようと思って、zipクレート(ライブラリー)を使った次のようなコードを書いていました(EPUBファイルは拡張子を変えたZIPアーカイブなのです)。

extern crate zip;

use std::fs;

fn main() {
    let path = std::env::args().nth(1).unwrap();
    let file = fs::File::open(&path).unwrap();

    let mut archive = zip::ZipArchive::new(file).unwrap();

    for i in 0..archive.len() {
        let mut f = archive.by_index(i).unwrap();
        let name = f.name().to_string();
        println!("{}", name);
    }

    let f = archive.by_name("META-INF/container.xml").unwrap();
    println!("{:?}", f.bytes().next().unwrap());
}

で、実行してみると、ファイル一覧は表示できる(println!("{}", name))のだけど、ファイルの中身を読み取る(f.bytes().next().unwrap())ところでエラー。

% cargo run api-design.epub
   Compiling handle-epub v0.1.0 (file:///Users/ikeda/src/gitlab.com/KitaitiMakoto/learning-rust/handle-epub)
error[E0599]: no method named `bytes` found for type `zip::read::ZipFile<'_>` in the current scope
  --> src/main.rs:18:24
   |
18 |     println!("{:?}", f.bytes().next().unwrap());
   |                        ^^^^^
   |
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
   |
3  | use std::io::Read;
   |

error: aborting due to previous error

error: Could not compile `handle-epub`.

zip::read::ZipFile<'_>bytesメソッドが無いと言われて、そんなばかなと思いつつzip::read::ZipFile構造体のAPIリファレンスを見ると

impl<'a> Read for ZipFile<'a>

fn bytes(self) -> Bytes<Self>
Transforms this Read instance to an [Iterator] over its bytes. Read more

やっぱりある。

ZipFileはちゃんとReadトレイトを実装しているのになーなんでだろうなー」と一日くらい悩んだのだけど、解決は一瞬でした。この悩み方に既にヒントが現れていて、悩んでいるうちに『プログラミング言語Rust』の次の文を思い出したのです。

第1に、あなたのスコープ内で定義されていないトレイトは適用されません。例えば、標準ライブラリは File にI/O機能を追加するための Write トレイトを提供しています。デフォルトでは、 FileWrite で定義されるメソッド群を持っていません。
(略)
始めに Write トレイトを use する必要があります。

(「トレイト」より)

というわけで答えは簡単、

use std::io::Read;

の一行を足すことで、あっさりとコンパイルが通ってコードも実行できたのでした。

% cargo run api-design.epub
   Compiling handle-epub v0.1.0 (file:///Users/ikeda/src/gitlab.com/KitaitiMakoto/learning-rust/handle-epub)
    Finished dev [unoptimized + debuginfo] target(s) in 0.90 secs
     Running `target/debug/handle-epub api-design.epub`
mimetype
META-INF/
META-INF/com.apple.ibooks.display-options.xml
META-INF/container.xml
OEBPS/
OEBPS/content.opf
OEBPS/images/
OEBPS/images/backslash.jpg
OEBPS/images/cover.jpg
OEBPS/images/p-001-000fig.jpg
OEBPS/images/p-001-001-1fig.jpg
OEBPS/images/p-001-001-2fig.jpg
...
OEBPS/text/p-005-003.xhtml
OEBPS/text/p-005-004.xhtml
OEBPS/text/p-005-005.xhtml
OEBPS/text/p-005-006.xhtml
OEBPS/text/p-006-001.xhtml
OEBPS/text/p-007-001.xhtml
OEBPS/text/p-008-001.xhtml
OEBPS/text/p-008-002.xhtml
Ok(60)