16
1

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 3 years have passed since last update.

SwiftAdvent Calendar 2020

Day 2

生成しないenum

Last updated at Posted at 2020-12-01

Qiita Advent Calendar 2020 Swift 2日目のエントリーです。

1日目「Swiftに搭載予定のC++相互運用機能」 は、
C++コードをSwiftコードとして呼び出せるようになる夢のような話でした。
ますますSwiftの時代ですね。

書いたこと

case値を持たないenumは生成することが出来ません。
その特性を利用して、enumは以下のような使い方も出来ます。

  • 名前空間としてのenum
  • 演算子の型を表すenum

名前空間としてのenum

SwiftはObjective-C同様、名前空間は正式サポートされていませんが、標準スタンダードライブラリーで用意されているUnicodeのようにUtility的な機能や定数をまとめる際に、名前空間としてenumが使用されます。

enum内部では以下の宣言が出来ます。

  • typealias
  • struct / enum / class
  • static let / static var / static func

使い所としては、以下のような場面が想定されます。

  • 定数をまとめる
  • Utility的な機能をまとめる

例1: 定数をまとめる

enumで定数をまとめる.swift
enum 👮 {
    static let name = "Mike"
    static let age = 32
    static let gender = 0
}
print(👮.name);

例2: Utility的な関数をまとめる

enumでUtility的な関数をまとめる.swift
enum Qiita {
    // URLを返す
    static func commentURL(_ commentId: String) -> URL {
        return URL(string: "\(scheme)://\(host)/\(Path.comments)/\(commentId)")!
    }

    // 定数をまとめる
    private static let scheme = "https"
    private static let host = "qiita"
    private enum Path {
        static let comments = "comments"
        static let users = "users"
        static let tags = "tags"
    }
}


print(Qiita.commentURL("14159265359"))

演算子の型定義

Arrayの添字に、...演算子を渡すことが出来ます。

Arrayはカスタムな演算子を添え字に渡せる.swift
let fruits = ["🍎", "🍌", "🍊", "🍐", "🍉"]
let sliced = fruits[...] // ArraySlice<String>  ["🍎", "🍌", "🍊", "🍐", "🍉"]

これは以下のようにメソッドが定義されているためです。

array.swift
subscript(x: (UnboundedRange_) -> ()) -> ArraySlice<Element> { get set }

このUnboundedRange_がenumです。

UnboundedRange_.swift
public enum UnboundedRange_ {
  public static postfix func ... (_: UnboundedRange_) -> () {
    fatalError("uncallable")
  }
}

UnboundedRange_内で、(UnboundedRange_) -> ()型が返すカスタム演算子...が定義されています。

これによって(UnboundedRange_) -> ()で宣言された引数に、...演算子を渡すことが出来ます。

まとめ

正式に名前空間がサポートされているC++、C#、PHPでは、名前空間を省略するための機能も用意されています。
(C++,C#ならば、using、PHPならば、use)

Swiftではどちらかというと上記の役割はモジュールが担っているところがあり、複雑になりかねないためサポートに踏み切れない理由がありそうです。

参照

以下の記事をまとめました。

https://qiita.com/takasek/items/3497188559fbf717751b
→ 「なぜ名前空間としてenumが使われるのか」について詳細に解説されています。

https://qiita.com/ysn/items/29363f0f6cc78d1d6561
→ カスタムの演算子の型の作り方を解説しています。

https://qiita.com/YOCKOW/items/dd409b9588f4be72f58f
→ UnboundedRange_型についてはこちらで詳しく解説されています。Array[...]の存在はこちらの記事でしりました。

16
1
4

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
16
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?