[Swift 문법] - 이니셜라이저, self, lazy, static, access control

sun02·2021년 7월 16일
0

100 days of Swift 

목록 보기
8/40

1. Initializers

이니셜라이저는 구조체를 만드는 다양한 방법을 제공하는 특별한 메서드이다.
모든 구조체들은 기본적으로 memberwiser initializer(멤버별 이니셜라이저)라고 불리는 것을 하나 가진다 – 이것은 구조체를 생성할 때 각 프로퍼티에 값을 주라고 요구한다.

struct User {
    var username: String
}
  • 한 개의 프로퍼티를 가지는 User 구조체이다.
var user = User(username: “twostraws”)
  • 우리는 위와 같은 구조체 중 하나를 생성할 때 username을 제공해야한다.

만약 모든 새로운 user들이 “Anonymous”로 생성되고 매세지를 출력하길 원한다면

struct User {
    var username: String

    init() {
        username = “Anonymous”
        print(“Creating a new user!”)
    }
}
  • 다음과 같이 디폴트 값을 대체하기 위해 이니셜라이져를 줄 수 있다.

이니셜라이저 앞에 func를 적을 필요는 없지만 이니셜라이저가 끝나기 전에 모든 프로퍼티들이 값을 가져야만 한다.

var user = User()
User.username = “twostraws”
  • 이니셜라이져는 매개변수를 받지 않기에 우리는 구조체를 다음과 같이 만들 수 있다.

2. Referring to the current instance

매서드 내에는 self라 불리는 특별한 상수가 있다.
이는 현재 사용 중인 구조체의 인스턴스를 가리킨다.
이 self 값은 프로퍼티와 이름이 같은 매개변수를 가진 이니셜라이져를 생성할 때 특히 유용하다.

struct Person {
    var name : String
 
    init(name: String) {
       print(“\(name) was born!”)
       self.name = name
    }
}
  • 다음과 같이 name 프로퍼티를 가지는 Person 구조체를 만들고 name 매개변수를 받아들이는 이니셜라이져를 작성하려 한다면
  • self로 프로퍼티와 매개변수를 구분할 수 있다 – self.name 은 프로퍼티를 참조하고, name 은 매개변수를 참조한다.

매서드에서 self를 언제 사용하는가?

매서드 내에서 우리는 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
    }
}
  • 지금까지 이니셜라이져 내에 self를 사용하는 가장 일반적인 이유는
    다음과 같이 프로퍼티 이름과 매개변수의 이름이 같게 하고 싶을 때 이다.
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가 그렇게 많이 필요하지 않아졌다.

3. Lazy properties

성능 최적화를 위해 Swift에서는 필요할 때만 프로퍼티를 생성할 수 있다.

struct FamilyTree {
    init() {
       print(“Creating family tree!”
    }
}
  • 여기 FamilyTree 구조체가 있다.
struct Person {
    var name: String
    var familyTree = FamilyTree()

    init(name: String) {
       self.name = name
    }
}

var ed = Person(name: “Ed”)
  • FamilyTree 구조체를 Person 구조체 안의 프로퍼티로 사용할 수 있다.

하지만 만약 특정 person에 대해 family tree가 필요하지 않는다면?

lazy var familyTree = FamilyTree()
  • 다음과 같이 familyTree 프로퍼티 앞에 lazy 키워드를 넣어 swift가 처음 접근할 때만 FamilyTree 구조체를 생성하게 한다.
ed.familyTree
  • 따라서, “Creating family tree!” 메세지를 보고 싶다면 이제 그 프로퍼티에 접근 해야한다.

4. Static properties and methods

여태까지 만든 모든 프로퍼티와 매서드는 구조체의 개별 인스턴스에 속해있었다.

struct Student {
    var name: String
  
    init(name: String) {
        self.name = name
    }
}


let ed = Student(name: ”Ed”)
let taylor = Student(name: “Taylor”)

}
  • Student 구조체를 갖고 있다면
    우리가 그들만의 고유한 프로퍼티와 매서드를 가지는 여러 스튜던트 인스턴스를 만들 수 있다는 의미이다.
struct Student {
    static var classSize = 0
    var name: String

    init(name: String) {
       self.name = name
       Student.classSize += 1
    }
}
  • 또한 static으로 선언하여 구조체의 모든 인스턴스에서 특정 프로퍼티와 매서드를 공유하도록 요청할 수 있다.
  • 교실에 얼마나 많은 학생이 있는지 저장하기 위해 Student 구조체에 정적 프로퍼티 classSize를 추가하였다. 새로운 student를 만들 때마다 하나가 추가된다.
print(Student.classSize)
  • classSize 프로퍼티는 구조체의 인스턴스가 아니라 구조체 그 자체에 속해있기 때문에, Student.classSize 를 사용해서 읽어야한다.

5. Access control

접근 제어는 코드가 프로퍼티와 매서드를 사용하는 것을 제어할 수 있게 한다. 사람들이 프로퍼티를 직접 읽지 못하게 하고 싶을 때 중요하다. 예를 들어

struct Person {
    var id: String

    init(id: String) {
       self.id = id
    }
}

let ed = Person(id: “12345”)
  • 주민등록번호를 저장할 id 프로퍼티를 가진 Person 구조체이다.
struct Person {
    private var id : String
  
    init(id: String) {
       self.id = id
    }
}
  • private 키워드를 사용해서 Person이 한 번 생성되면 구조체 밖에서 이것을 읽을 수 없도록 id를 비공개로 만들 수 있다. – ed.id 를 적는 것으로 실행되지 않는다.
struct Person {
    private var id : String
   
    init(id: String) {
        self.id = id
    }

    func identify() -> String {
         return “My social security number is \(id)”
    }
}
  • 이제 Person안의 매서드만 id프로퍼티를 읽을 수 있다.

또다른 자주 사용되는 것에는 public 이 있다. 이것은 모든 다른 코드들이 프로퍼티나 매서드를 사용할 수 있게 한다.

출처

0개의 댓글