이니셜라이저는 구조체를 만드는 다양한 방법을 제공하는 특별한 메서드이다.
모든 구조체들은 기본적으로 memberwiser initializer(멤버별 이니셜라이저)라고 불리는 것을 하나 가진다 – 이것은 구조체를 생성할 때 각 프로퍼티에 값을 주라고 요구한다.
struct User {
var username: String
}
var user = User(username: “twostraws”)
만약 모든 새로운 user들이 “Anonymous”로 생성되고 매세지를 출력하길 원한다면
struct User {
var username: String
init() {
username = “Anonymous”
print(“Creating a new user!”)
}
}
이니셜라이저 앞에 func를 적을 필요는 없지만 이니셜라이저가 끝나기 전에 모든 프로퍼티들이 값을 가져야만 한다.
var user = User()
User.username = “twostraws”
매서드 내에는 self라 불리는 특별한 상수가 있다.
이는 현재 사용 중인 구조체의 인스턴스를 가리킨다.
이 self 값은 프로퍼티와 이름이 같은 매개변수를 가진 이니셜라이져를 생성할 때 특히 유용하다.
struct Person {
var name : String
init(name: String) {
print(“\(name) was born!”)
self.name = name
}
}
매서드 내에서 우리는 self를 사용해서 구조체의 현재 인스턴스를 참조할 수 있지만
일반적으로 의미하는 바를 특별히 구분해야 하는 경우가 아니면 필요하지 않다.
struct Student {
var name: String
var bestFriend: String
init(name: String, bestFriend: String) {
print(“Enrolling \(name) in class…”)
self.name = name
self.bestFriend = bestFriend
}
}
Struct Student {
var name: String
var bestFriend: String
init(name studentName: String, bestFriend studentBestFriend: String) {
print(“Enrolling \(studentName) in class..”)
name = studentName
bestFriend = studentBestFriend
}
}
이니셜라이져 밖에서, self를 사용하는 주된 이유는
우리는 클로져 안에 있고 무엇이 일어나고 있는지 확실히 이해하기 위해서 스위프트가 그렇게 하도록 요구하기 때문이다.
Swift 5.3이후로 이 상황은 매우 개선되어 일반 매서드에서 self가 그렇게 많이 필요하지 않아졌다.
성능 최적화를 위해 Swift에서는 필요할 때만 프로퍼티를 생성할 수 있다.
struct FamilyTree {
init() {
print(“Creating family tree!”
}
}
struct Person {
var name: String
var familyTree = FamilyTree()
init(name: String) {
self.name = name
}
}
var ed = Person(name: “Ed”)
하지만 만약 특정 person에 대해 family tree가 필요하지 않는다면?
lazy var familyTree = FamilyTree()
ed.familyTree
여태까지 만든 모든 프로퍼티와 매서드는 구조체의 개별 인스턴스에 속해있었다.
struct Student {
var name: String
init(name: String) {
self.name = name
}
}
let ed = Student(name: ”Ed”)
let taylor = Student(name: “Taylor”)
}
struct Student {
static var classSize = 0
var name: String
init(name: String) {
self.name = name
Student.classSize += 1
}
}
print(Student.classSize)
접근 제어는 코드가 프로퍼티와 매서드를 사용하는 것을 제어할 수 있게 한다. 사람들이 프로퍼티를 직접 읽지 못하게 하고 싶을 때 중요하다. 예를 들어
struct Person {
var id: String
init(id: String) {
self.id = id
}
}
let ed = Person(id: “12345”)
struct Person {
private var id : String
init(id: String) {
self.id = id
}
}
struct Person {
private var id : String
init(id: String) {
self.id = id
}
func identify() -> String {
return “My social security number is \(id)”
}
}
또다른 자주 사용되는 것에는 public 이 있다. 이것은 모든 다른 코드들이 프로퍼티나 매서드를 사용할 수 있게 한다.