TL; DR
someはOpaque Result Typeを表すためのキーワード- プロトコル型(Existential Type)と比較して、大きく2つの利点がある
- 実行時のオーバーヘッドがない
- 具体的な型を隠蔽できる
こんにちは。インターンシップにメンターとして参加した傍らSwiftUIを勉強しようと思っていたら、出会い頭に謎の刺客に攻撃されました。
その刺客とはそう、
someです。
struct MyView: View {
var body: some View { // こいつ
Text("Hello World")
}
}
分からないものを調べようとしたら別の分からないものに遭遇する感じ、久々ですね。
SwiftUIについてちゃんと理解を深めるために、まずはこの
someを理解することにしました。備忘録として、そして自己の理解を深めるためのアウトプットとして残しておきます。
someとは
「とあるプロトコルを批准する何らかの型」を表すための構文です。 プロパティやメソッドの返り値の型を抽象化する(Opaque Result Type)のに用いられます。
Swift5.1から新しく追加されています。
// プロトコルHogeを批准する何らかの型の変数hoge
var hoge: some Hoge = Fuga()
// プロトコルHogeを批准する何らかの型のインスタンスを返すメソッド
func returnHoge() -> some Hoge {
return Fuga()
}
正直これだけの情報では???という感じなので、ひとつずつ紐解いていきます。
プロトコル型(Existential Type)とジェネリクスの違い
プロトコル型とジェネリクスは、「使う側が具体的な型を知っていて、使われる(実装する)側は抽象的な型(プロトコル)を知っている」という点では同じですが、パフォーマンスの面では結構異なるようです。
func testHoge(hoge: Hoge) { ... }→hogeはHogeを批准するプロトコル型(Existential Type)の定数func testHoge(hoge: T) { ... }→hogeはHogeを批准する何らかの型の定数
プロトコル型で変数を定義した場合、Existential Containerのラップにより、実行時に確保されるメモリの量が増えます。 しかし、ジェネリクスで変数を定義した場合、コンパイラによって型が特定されるため実行時のオーバーヘッドが発生しません。よって、パフォーマンスの面でジェネリクスに優位性があります。
永田駿平
iOSアプリを作っています
音楽とガジェットが好きです