7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rustの文字列で、1文字ずつ大文字/小文字の変換をする

Last updated at Posted at 2016-10-16
  • Rustの勉強を始めて3日目ぐらいでハマりました。より良い方法を教えていただきたいので投稿します。普段はPythonです。
  • 間違っているところ、Rustの理念に反しているところがたくさんあると思いますので、ご指摘よろしくお願いします。

##何をやりたいか

  • yukicoderのNo.163
  • 文字列中の小文字を大文字に、大文字を小文字に変換したい
  • Ex) CapsLock -> cAPSlOCK

##TL;DR
皆様のコメントを受けて以下のようになりました。
(@takayahiltonさん、@tatsuya6502@woxtuさんありがとうございました。)

fn capslock(c: char) -> char {
    if c.is_uppercase() {
        c.to_ascii_lowercase()
    } else {
        c.to_ascii_uppercase()
    }
}

fn convert(string: &str) -> String {
    string.chars().map(capslock).collect()
}

##はまった箇所

  • 1文字ずつ変換を行わなければいけないのでとりあえずmap関数にかけたい。
  • 文字列をchar型のiteratorに変換するのはchars()を使うらしい
  • char型にはis_uppercase()やto_uppercase()などがあるのでこれは使えそう
  • 簡単のために一文字ずつ大文字に変換するコードを素直に書くと
// エラー
fn convert(string: &str) -> String {
	string.chars().map(|x| x.to_uppercase()).collect::<String>()
}
  • これがなぜエラーになるかというとto_uppercase()がiteratorを返すから
  • なぜiteratorを返すかというと大文字のコードポイントが複数になる場合があるかららしい(参照)
  • 複数のコードポイントを返すのは'fi' -> "FI"'ß' -> "SS"などの合字が返ってくる可能性があるから(@takayahiltonさんありがとうございました。)
  • このiteratorをstring/&strに変更する方法がよくわからなかったので、charをstringにしてから大文字に変更する戦略へ
  • mapをflat_mapに変更するとこのまま動きます。(@takayahiltonさんありがとうございました。)

##皆様のコメントを受けて

  • 英語のみに対応するのであれば、char型のto_uppercase()ではなくto_ascii_uppercase()を利用するのが楽

##コード

use std::ascii::AsciiExt;

fn getline() -> String{
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok();
    ret
}

fn capslock(c: char) -> char {
    if c.is_uppercase() {
        c.to_ascii_lowercase()
    } else {
        c.to_ascii_uppercase()
    }
}

fn convert(string: &str) -> String {
    string.chars().map(capslock).collect()
}

fn main() {
    let s = getline();

    println!("{}", convert(s.trim()));
}

##感想

  • 本当はchars()を使ってはいけないんだと思う(コードポイントが1つになるとは限らないので)
  • しかしgrapheme関連のAPIがunstableなので断念
  • C++をやりたくがないために勉強をしているが、Rustのありがたみを知るためにはC++の知識が必要そうです。
  • Rubyに近い?
7
4
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?