static について馴染みがなく、理解するのに少し時間がかかったので備忘録。

static はクラスやクラスプロパティの宣言時に class キーワードをつけるような感覚で、プロパティやメソッドの宣言時に使う。

class Cat {
  static let sex: String = "male"

  func eat() {}
  static func meow() {}
}

// メソッド呼び出し時にCatクラスのインスタンスが毎回生成される。Cat().eat()

// Catクラスのインスタンスを生成せずに参照する。Cat.meow()

static キーワードを使ってプロパティやメソッドを宣言すれば、そのクラスの全インスタンスで共通して利用することができる。

参照する際にはインスタンス生成されないので、メモリの使用量を抑えることができる。

class Credential {
  static let secretKey = "xxx"
}

// クラスのインスタンス化は可能
let credential = Credential()
class Credential {
  static let secretKey = "xxx"

  // イニシャライザのスコープをクラス内に絞る
  private init() {}
}

// インスタンス化を防ぐことができる
let credential = Credential() // 'Credential' initializer is inaccessible due to 'private' protection level

// プロパティへのアクセスはもちろん可能
let credential = Credential.secretKey

// ただし引数として渡すことはできてしまう
func authorize(credential: Credential) {
  print("認可しました。")
}
enum Credential {
  static let secretKey = "xxx"
}


// 🙆‍♂️
let credential = Credential.secretKey

// `private init()` を書かなくてもインスタンス化を防ぐことができる
let credential = Credential() // 'Credential' cannot be constructed because it has no accessible initializers

// enumを引数として渡しているので、コンパイラが警告を出してくれる
func authorize(credential: Credential) {
  print("認可しました。") // Will never be executed
}

このように case なしの enum でstaticプロパティを宣言すれば、インスタンスが生成されることはなくなり、ネームスペース的にプロパティやメソッドを呼び出すことができる。


参考サイト

(teratail) static という言葉の意味が分からない。

Swift におけるシングルトン・staticメソッドとの付き合い方

【swift】イラストで分かる!classとstructの違いについて【初心者向け】

Swiftではnamespaceとしてcaseなしenumが使える