【Swift】「UnicodeScalar」とは、いわゆる「コードポイント !」だったのか ☀️

高校生のときに聞いたことある「スカラー」。

〘名〙 (scalar) 長さ、面積、重さなど、大きさだけで定まる量。常識上の数。ベクトルに対していう。スケーラー。

👉 スカラーとは? 意味や使い方 - コトバンク hatena-bookmark

「方向がない」という雰囲気だけ覚えていたけども。

 

☀️ UnicodeScalar

以下、サンプルコード。


let data = [
  ["61"],
  ["3042"],
  ["1F635", "200D", "1F4AB"],
  ["1F468", "200D", "2764", "FE0F", "200D", "1F468"],
  ["1F1EF", "1F1F5"]
]

for codepoints in data {
  let s = String(
    codepoints
      .map { Int($0, radix: 16)! }
      .map { UnicodeScalar($0)! }
      .map { Character($0) }
  )
  print(s)
  print(codepoints)
  print(
    s.unicodeScalars
      .map { String($0.value, radix: 16, uppercase: true) }
  )
  print()
}

変換の流れ的には以下の順序で変換。


[Int]

  ↕

[UnicodeScalar]

  ↕

[Character]

  ↕

String([Character])

 

☀️ まとめ

「UnicodeScalar」とは「コードポイント !」のことですね。

nil は許しません。

String.unicodeScalars() は、文字のコードポイントパーサーとしても使えます。

👉 Strings and Characters | Documentation hatena-bookmark


【Swift】「public」 を省略しない理由 🚫

iOS アプリの Apple 公式ドキュメントや著名作者のコードをあれこれ眺めていて気になっていたのは、

「なんで public を省略しないのか」

ということ。


public extension Image {
    static let fountain = Image(.fountain)
    static let fountainFill = Image(.fountainFill)
}

👉 sample-backyard-birds/BackyardBirdsUI/Images.swift at 1843d5655bf884b501e2889ad9862ec58978fdbe · apple/sample-backyard-birds hatena-bookmark

「はっきり明示する。」

のがポリシーなのかと思ったが省略してる箇所もある。

なんでなの ?

 

🚫 '***' is inaccessible due to 'internal' protection level

試しに消してみると、


extension Image {
    static let fountain = Image(.fountain)
    static let fountainFill = Image(.fountainFill)
}

呼んでいる場所でエラー発生。


'fountain' is inaccessible due to 'internal' protection level

見えてはいるけどアクセスができない。

 

🚫 まとめ

Java など他の言語とは違います。

アクセスレベルを省略した場合は「internal」。

同じモジュール内からしかアクセスできません。

移民はつらい。

しかし、さすが公式サンプルコードは勉強になります。

しっかりしています。

👉 Access Control | Documentation hatena-bookmark


【Swift】よくある enum extension の switch ~ case のイメージ

頻繁に見かけるんですけど、

いまいち分かってない以下のような記述。

これは一体なんなのか。

すごく冗長に見えるし。

ぱっと見、理解できなかったので、

基本的な部分を少し噛み砕いてみました。

順番にやっていきます。

 

🤔 enum

まず、列挙型の enum。


enum Animal {
  case dog
  case cat
  case monkey
}

また、次のように書いても同じ。


enum Animal {
  case dog, cat, monkey
}

case がいるんですね !

 

🤔 extension で switch ~ case 追加

extension で拡張して追加。


enum Animal {
  case dog, cat, monkey
}

extension Animal {
  var hiragana: String {
    switch self {
      case .dog: "いぬ"
      case .cat: "ねこ"
      case .monkey: "さる"
    }
  }
}

print(Animal.cat.hiragana)
// ねこ

紐づくんですね。

それぞれの enum 要素に。

 

🤔 さらにもう一つ追加


enum Animal {
  case dog, cat, monkey
}

extension Animal {
  var hiragana: String {
    switch self {
      case .dog: "いぬ"
      case .cat: "ねこ"
      case .monkey: "さる"
    }
  }

  var katakana: String {
    switch self {
      case .dog: "イヌ"
      case .cat: "ネコ"
      case .monkey: "サル"
    }
  }
}

print(Animal.cat.hiragana)
print(Animal.monkey.katakana)
// ねこ
// サル

そういうことか !

enum の「それぞれの要素から枝が生えていく」のか !

 

🤔 まとめ

どうやら考え方としては、

ベースの enum のそれぞれの要素に extension で枝を生やしていく

ようなイメージでいいのでしょうか。

ネストしたデータ構成の編集時に便利に使えそうです。

推測できれば、クラス名の省略ができることも良い !

しかし、Swift の enum は機能豊富らしいけど、

まずは、これくらいでいいかな。