CharacterをStrideableプロトコルに準拠させる一工夫【swift】

# はじめに
- [前回の投稿](https://qiita.com/kei_tnk/items/871c71ffe84b7caf12a2)につづいて、swiftの不甲斐なさのあまり、怒りにまかせて一工夫してしまった。

# Character型の特徴
- 競技プログラミングしてると、文字列(String)を扱うことが頻繁にあるけど、文字列を分解するため配列にすると、その要素はCharacter型になる。
```swift
let a = "a"
print(type(of:a)) // String

let abc = "abc"
let ary = Array(abc)
print(ary) // ["a", "b", "c"]
print(type(of:ary)) // Array<Character>
print(String(ary)) // "abc"

let c:Character = "c"
print(type(of:c)) // Character
// let cd:Character = "cd" -- error 二文字は駄目！
```
- Character型の特徴については、上記コードのとおり。
- で、Character型は、"a"の次は"b"という順序もあるから、こんなコードが可能かな？と思ったところ、イケたんだよ！
```swift
let az = "a" as Character ... "z" // -- この書き方は最新のswiftでは駄目みたい(詳細は、後述)
print(type(of:az)) // ClosedRange<Character>

print(az.contains("d")) // true
print(az.contains("D")) // false
```
- ここまで来たら、当然、これイキますわ
```swift
let az = "a" as Character ... "z" // -- この書き方は最新のswiftでは駄目みたい(詳細は、後述)
for c in az {
    print(c)
}
-- error : protocol 'Sequence' requires that 'Character' conform to 'Strideable'
```
- はい、出ました、クソ仕様によるエラー！<font color="red">Character型で作ったレンジはStrideableプロトコルに準拠してないからfor文に使えません！！！</font>
- 大事なことなので、もう一回言います。<font color="red">Character型で作ったレンジはStrideableプロトコルに準拠してないからfor文に使えません！！！</font>
- ふざけんな〜〜〜！！！（全国50人くらいの swiftで競技プログラムしている人達 の声）
- なので、Character型で作ったレンジをfor文で使いたい人のために、このコードを捧げます。まぁ、swiftで競技プログラミングしてる人なら、...以下略

# swiftで苦労している君に捧げるコード
- Strideableは次の2つのメソッドが必須です。
    - advanced(by n: Int)
        - nズラした値を返す。例えば、`"c".advanced(by:2) -> "e"` のイメージ。
    - distance(to other: Self)
        - 2つの値の差を返す。例えば、`"c".distance(to:"f") -> 3` のイメージ。
- じゃあ、つくります。
```swift
extension Character: Strideable {
    public func advanced(by n: Int) -> Self {
        return Character(UnicodeScalar(Int(self.asciiValue!) + n)!)
    }
    public func distance(to other: Self) -> Int {
        return Int(other.asciiValue!) - Int(self.asciiValue!)
    }
}

let a_z = "a" as Character ... "z" // -- この書き方は最新のswiftでは駄目みたい(詳細は、後述)
for c in a_z {
    print(c,terminator:"") // abcdefghijklmnopqrstuvwxyz
}
print(Character("a").advanced(by:2)) // c
print(Character("a").distance(to:"d")) // 3
```
- うむ、成功！！
- でも、extensionの実装内容は意外と分かりづらいよね。文句はswift君に言ってくれ。一応説明すると、
    - .asciiValue
        - ASCIIコードを返します。オプショナル型のUInt8が返るので！を付けて、Int化が必要。
        - ちなみに、"あ".asciiValueはnilとなります。"あ"はascii文字じゃないからね。
    -  UnicodeScalar
        - Characterのイニシャライザが、asciiコードを受け付けないから、一度、UnicodeScalarをかます必要がある。本当に無駄よね。でもまぁ、Characterさんの事情もあるから許してあげよう。
        - ちなみに、CharacterとUnicodeScalarの関係は、次を見て貰えば､なんとなく分かるだろうか。
        - そういえば、`typealias UnicodeScalar = Unicode.Scalar`です
            ```swift
            let ka = "\u{304B}" as Unicode.Scalar
            let daku = "\u{3099}" as Unicode.Scalar
            // let ka_daku = "\u{304B}\u{3099}" as Unicode.Scalar -- エラー
            let ga = "\u{304C}" as Unicode.Scalar
            print(ka,daku) // か ゙
            
            let ka_c = "\u{304B}" as Character
            let daku_c = "\u{3099}" as Character
            let ka_daku_c = "\u{304B}\u{3099}" as Character
            let ga_c = "\u{304C}" as Character
            print(ka_c,daku_c,ka_daku_c,ga_c) // か ゙ が が
            
            print(ka_daku_c == ga_c) // true
            
            let ka_num = Unicode.Scalar(0x304b)
            // let ka_c_num = Character(0x304b) -- エラー
            
            let ka_c_num = Character(Unicode.Scalar(0x304b)!)
            
            print(ka_num!) // か
            print(ka_c_num) // か
            ```
        - Characterは、"\u{304B}\u{3099}"と"\u{304C}" が一致するのがポイント高いよね。だからこそ、Characterは数値でイニシャライズできず、UnicodeScalarをかまさないと駄目なんだろうね。糞面倒。
        - ちなみに、このextensionは、a-zやA-Zではつかえるけど、ascii文字じゃない「あ〜ん」では使えないから注意してね。
:::note warn
注意！！！

Characterのレンジ生成で、最新のswiftでは、
× `let a_z = "a" as Character ... "z"`
　の表記は駄目になったみたいです。
 
「paiza.io」ではイケたけど、「atcoderの提出」ではアウト。

○`let a_z = ("a" as Character) ... "z"`
○`let a_z = Character("a")..."z"`
　ならイケます。 
 
　駄目になった書き方の方が、スッキリしてて、オシャレで好きなのに...
:::

# さいごに
- a-zをレンジに出来るなら、forのレンジでも使わせてくれ！
- [a,c,e,...]のような、一つ飛ばしみたいな使い方をするつもりもないのに、Strideableに強制的に準拠させようとしないで欲しいです。