質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

2回答

4828閲覧

[(&str, &str); 6]な配列の全要素のタプルについて1番目と2番目を入れ替えvectorに変換するには

yumetodo

総合スコア5850

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

0クリップ

投稿2019/01/31 11:14

rust

1const TABLE1: [(&str, &str); 6] = [ 2 ("a", "あ"), ("i", "い"), ("u", "う"), ("e", "え"), ("o", "お"), 3 ("n", "ん") 4];

のような配列があったとき、

rust

1vec![ 2 ("あ", "a"), ("い", "i"), ("う", "u"), ("え", "e"), ("お", "o"), 3 ("ん", "n") 4]

と等価なVec<(&str, &str)>へ変換したいです。

rust

1TABLE1.iter().map(|(s1, s2)| (s2, s1)).cloned().collect::<Vec<(&str, &str)>>()

のようにすれば行けないかと思いましたが、これでは

error[E0271]: type mismatch resolving `<std::iter::Map<std::slice::Iter<'_, (&str, &str)>, [closure@src\cvt\jis_x_4063_2000.rs:94:27: 94:46]> as std::iter::Iterator>::Item == &_` --> src\cvt\jis_x_4063_2000.rs:94:48 | 94 | TABLE1.iter().map(|(s1, s2)| (s2, s1)).cloned().collect::<Vec<(&str, &str)>>(), | ^^^^^^ expected tuple, found reference | = note: expected type `(&&str, &&str)` found type `&_` error[E0599]: no method named `collect` found for type `std::iter::Cloned<std::iter::Map<std::slice::Iter<'_, (&str, &str)>, [closure@src\cvt\jis_x_4063_2000.rs:94:27: 94:46]>>` in the current scope --> src\cvt\jis_x_4063_2000.rs:94:57 | 94 | TABLE1.iter().map(|(s1, s2)| (s2, s1)).cloned().collect::<Vec<(&str, &str)>>(), | ^^^^^^^ | = note: the method `collect` exists but the following trait bounds were not satisfied: `std::iter::Cloned<std::iter::Map<std::slice::Iter<'_, (&str, &str)>, [closure@src\cvt\jis_x_4063_2000.rs:94:27: 94:46]>> : std::iter::Iterator` `&mut std::iter::Cloned<std::iter::Map<std::slice::Iter<'_, (&str, &str)>, [closure@src\cvt\jis_x_4063_2000.rs:94:27: 94:46]>> : std::iter::Iterator` error: aborting due to 2 previous errors

のようにエラーになってしまいます。というかexpected tuple, found referenceってどういうことなんでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

すでに動くコードが示されていますが、エラーの原因についてだけ説明します。まず説明のため質問のコードを整形します。

rust

1TABLE1 2 .iter() // : Iterator<Item = &(&str, &str)> 3 // (*) 4 .map(|(s1, s2)| { 5 (s2, s1) // : (&&str, &&str) 6 }) // : Iterator<Item = (&&str, &&str)> 7 .cloned() // ERROR 8 .collect::<Vec<(&str, &str)>>()

(*)においてこの時点でイテレータのアイテムの型は&(_, _)の形ですが、mapのクロージャの引数は(_, _)の形をしています(つまり&が欠けている)。このような場合、クロージャの引数は&(ref s1, ref s2)のように脱糖されます(これはmatch ergonomicsと呼ばれる機能によるものです)。つまりs1s2の型は&&strになってしまいます。ここで引数を&(s1, s2)とするか、別の回答のように返り値を(*s2, *s1)とすれば期待通り&strを返すようになります。

また、Iterator::cloneSelf: Iterator<Item = &'a T>、つまりイテレータのアイテムが参照であることを要求しますが、ここでmap後の要素は参照(&(_, _))でなく(_, _)であり、clonedは使えません(というより不要です)。

投稿2019/01/31 12:21

tesaguri

総合スコア33

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

下記コードで目的達成するでしょうか。

rust

1const TABLE1: [(&str, &str); 6] = [ 2 ("a", "あ"), ("i", "い"), ("u", "う"), ("e", "え"), ("o", "お"), 3 ("n", "ん") 4]; 5 6fn main() { 7 let vec = TABLE1.iter().map(|(s1, s2)| (*s2, *s1)).collect::<Vec<_>>(); 8 for e in vec { 9 println!("{} {}", e.0, e.1); 10 } 11}

追記:.map(|(s1, s2)| (s2, s1)) でも十分ですね。

投稿2019/01/31 11:23

編集2019/01/31 11:55
yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tesaguri

2019/01/31 12:23

追記に関して、`.map(|(s1, s2)| (s2, s1))`だけだと`Vec<(&str, &str)`でなく`Vec<(&&str, &&str)>`になってしまいますね(場合によってはそれでも十分かもしれませんが)。
yohhoy

2019/01/31 12:24

はい、その通りですね。コードを色々いじっていて後で気づきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問