2016-04-08 7 views
1

私は列挙型は、(あなたは私が構築しようとしているものを推測することができますか?:P)Tokenと呼ばれてい非構造Vecを<列挙型(文字列)>を反復しながら、

それは、このような非常に多くなります:

enum Token { 
    Paren(String), 
    Number(String), 
    Name(String), 
} 

は今、私は次のシグネチャを持つ関数があります。

fn tokenizer(input: String) -> Vec<Token>

を私はそれが基本的に働いていないと信じる理由はないので、私はobvio uslyはVec<Token>です。

さて、私の主な機能には、私はこれがあります。

let tokens = tokenizer("(add 44 5)".to_owned()); 

を、私はのように次のような何かをしたいと思います:

let mut iter = tokens.iter(); 
while let Some(token) = iter.next() { 
    match token { 
     Token::Paren(p) => println!("Token::Paren({})", p), 
     Token::Number(p) => println!("Token::Number({})", p), 
     Token::Name(p) => println!("Token::Name({})", p), 
    } 
} 

しかし、明らかにボロー・チェッカーISN」私はとても簡単に降りることができます。

これを行うには適切な方法はありますか?明らかに、このプロジェクトの性質によってうまく説明できるように、私は単にRustを学ぼうとしているだけなので、本当に問題に直接関係していないとしても助言は役に立ちます。 =)

答えて

3

あなたの列挙型は、渡されたので、彼らは)値によってそれらを捕獲(と列挙型の外に移動しようとする構造化代入された文字列を所有しています。

参照してキャプチャする構造化代入しているときには、動きを止める。.. ref pを使用してこの問題を解決することができます。あなたは、ベクター内のトークンへの参照を返すiter()を使用しているので、あなたはまた、トークンを逆参照する必要があります

match *token { 
    Token::Paren(ref p) => println!("Token::Paren({})", p), 
    Token::Number(ref p) => println!("Token::Number({})", p), 
    Token::Name(ref p) => println!("Token::Name({})", p), 
} 

Working sample on the Playpen

注意。 into_iter()を使用した場合、所有権が譲渡され、非参照で一致することができます。ただし、値が移動されると、tokens変数が破損するようになりました。

+0

私のヒーロー!私がマッチブロック内でパターンマッチングを行っているので、別の質問をするかもしれませんが、それは動き、コピー、あるいはその両方を引き起こしますか?私は錆にはとても新しいです。 =) –

+1

どのようにキャプチャするかによって異なります。あなたは値で 'p'を捕捉していたので、あなたのオリジナルは移動を引き起こしていた(または移動しようとしていた)。 'ref'を使用すると参照で取得されますので、移動しません。ここでは他に考慮すべきことがありますが、マッチブロックが実際のコードブロックになり、複雑になるだけで説明する必要があります。考慮すべき他のものはあなたのタイプが 'コピー'かどうかですが、それについては後で心配してください:) –

+1

'match * token {...}'と書くのは慣用句と考えられます。 –

関連する問題