67807


Rustで書かれた下記のコードについて2点質問です。

まず状況としては、`hoge3`のコメントアウトを外してコンパイルすると次のようなエラーメッセージが出現します。

[code]

    fn main() {
        let hoge : Vec<&str> = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.".split(' ').collect();
        let hoge2 = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.".split(' ').collect::<String>();
        // let hoge3 = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.".split(' ').collect::<&str>();
    }
    
[/code]

[code]

    error[E0277]: a value of type `&str` cannot be built from an iterator over elements of type `&str`
     --> src/main.rs:5:125
      |
    5 |     let hoge3 = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.".split(' ').collect::<&str>();
      |                                                                                                                             ^^^^^^^ value of type `&str` cannot be built from `std::iter::Iterator<Item=&str>`
      |
      = help: the trait `std::iter::FromIterator<&str>` is not implemented for `&str`
    
[/code]

  1. `hoge3`がコンパイルエラーとなるのは&strがFromIteratorトレイトを実装していないからというのはエラー文から分かるのですが、なぜ&strはこのトレイトが実装されていないのでしょうか？
  2. また、`hoge`ではcollect()に型指定をしないことで戻り値がVec<&str>になっていますが、これはVec<&str>以外にも指定できる型があるということでしょうか？変数`hoge`への型指定をせずにコンパイルするとコンパイラが型を決定できずにコンパイルエラーが出ました。型を決定できないということは他にも考えられうる型の候補がいくつかあったと考えられそうですが、もしそうだとしたらどんな型が候補に上がったのでしょうか？


CC BY-SA 4.0
2020-06-19T05:44:04.473
67806
2020-06-19T06:22:15.650
40229
question
rust
文字列に対するcollectの型処理について


## 1\. `FromIterator<&str> for &str` がない理由

`&str` は借用された文字列の型です。より端的には「どこかに既にある文字列を指す」ことしかできません。  
`T: FromIterator<A>` は「Aを集めて **新たに** Tを作る」ものですから、「どこかに既にある文字列」の型である `&str`
を直接作るためには使えないのです。

## 2\. `.collect()` で作れる型

collect() で作れる型かどうかは、まさに `FromIterator` trait により決められています。  
`{&strのイテレータ}.collect::<Vec<&str>>` ができるのは、`impl<T> FromIterator<T> for
Vec<T>` が実装されているからです (この場合、要素型 T は `&str` です)。

[FromIterator のドキュメントで一通り列挙されている](https://doc.rust-
lang.org/stable/std/iter/trait.FromIterator.html#implementors) ので、そちらを見ると
collect() で作れる標準ライブラリ中の型は網羅されています。

今回のケースでは、 `String`, `Cow<'_, str>`, `VecDeque<&str>`, `BTreeSet<&str>`,
`HashSet<&str>` などを作ることができることがわかります。


CC BY-SA 4.0
2020-06-19T06:22:15.650
67807
2020-06-19T06:22:15.650
32355
67806
answer