はじめに
ふと「イニシャライザ(コンストラクタ)と Self
を返すstatic funcの使い分けって何だろう?」と思ったので、自分の言葉でまとめてみます。
あくまで自分の考えなので、参考程度に留めてもらえればと思います。
環境
- OS: macOS Sonoma 14.5
- Xcode: 16.2 (16C5032a)
- Swift: 6.0.3
注意
あくまで「 Self
を返すstatic func」とイニシャライザの比較なので、BuilderパターンやFactory Methodパターンなどの複雑なパターンについては本記事では考慮しません。
結論
まず結論を述べます。
static funcはstatic letやstatic varも含めます。
- インスタンスに名前を付けられる → static func
- インスタンスに名前を付けられない → init
たったこれだけです。
インスタンスに名前を付けられる
インスタンスに名前を付けられる場合はstatic funcを使います。
この説明だけではピンと来ないかもしれないので、具体例を挙げます。
例1: 特別な値を返す
特別な値を返す場合、意味がわかるように名前を付けます。
例えばSwiftUIの Color
で赤を返す場合は red
、青を返す場合は blue
と名付けられるのでstatic funcとします。
public struct Color {
public static let red: Self = ...
public static let blue: Self = ...
}
Text("Foo")
.foregroundStyle(.red)
initでも実現できますが、冗長になります。
public struct Color {
public enum Type {
case red
case blue
}
public init(type: Self.Type) {
switch type {
case .red: ...
case .blue: ...
}
}
}
Text("Foo")
.foregroundStyle(.init(type: .red))
例2: Singletonパターン
よく使われるパターンとして、Singletonパターンを紹介します。
shared
や current
などと名付けることが多いです。
Singletonを実現するため、initはprivateにします。
public final class FooDataSource {
public static let shared: FooDataSource = .init()
private init() {}
public func foo() {
...
}
}
FooDataSource.shared.foo()
これでSingletonのインスタンスを呼び出しているとわかりやすくなります。
インスタンスに名前を付けられない
インスタンスに名前を付けられない場合はinitを使います。
例1: カラーコードから色を生成する
例えば16進数のカラーコードから Color
を生成する場合、カラーコードによって赤にも青にもなり得るため、名付けられません。
public struct Color {
public init(hex: String) {
...
}
}
let red: Color = .init(hex: "#FF0000")
例2: 引数を保持するだけ
渡された引数をそのまま保持したり、少しだけ加工したりする場合も、名付けられないのでinitを使います。
public struct Foo {
public let title: String
public let description: String
public let url: URL?
public init(
title: String,
description: String,
urlString: String
) {
self.title = title
self.description = description
self.url = URL(string: urlString)
}
}
let foo: Foo = .init(
title: "Foo",
description: "Bar",
urlString: "https://example.com"
)
よく見るinitだと思います。
おわりに
自分なりにinitとstatic funcの使い分けを考えてみましたが、どうでしょうか。
名付けられなくても加工する処理が重い場合はinitでなくstatic funcを使うなど、他の観点もあると思います。
ぜひ本記事と異なる観点があればコメントなどで教えてもらえると嬉しいです