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 👮 {
static let name = "Mike"
static let age = 32
static let gender = 0
}
print(👮.name);
例2: Utility的な関数をまとめる
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の添字に、...
演算子を渡すことが出来ます。
let fruits = ["🍎", "🍌", "🍊", "🍐", "🍉"]
let sliced = fruits[...] // ArraySlice<String> ["🍎", "🍌", "🍊", "🍐", "🍉"]
これは以下のようにメソッドが定義されているためです。
subscript(x: (UnboundedRange_) -> ()) -> ArraySlice<Element> { get set }
このUnboundedRange_
がenumです。
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[...]の存在はこちらの記事でしりました。