티스토리 뷰

Swift/야곰의 스위프트

2회독 정리

할루루 2018. 10. 3. 17:22
2회독

연산자

사용자 정의 연산자

토큰으로 사용되는 =, ->, //, /*, */ 등과 전위 연산자 <, &, ?, 중위 연산자 ?, 후위 연산자 >, !, ? 등은 Swift에서 예약한 상태이므로 재정의할 수 없으며 사용자 정의 연산자로 사용될 수 앖다.

전위 연산자 정의와 구현

prefix operator **
prefix func **(value: Int) -> Int {
    return value * value
}

후위 연산자 정의와 구현

postfix operator **
postfix func **(value: Int) -> Int {
    return value * value
}

중위 연산자 정의와 구현

중위 연산자는 우선순위 그룹precedenceGroup을 명시해줄 수 있음

precedenceGroup 우선순위_그룹_이름 {
    higherThan: 더_낮은_우선순위_그룹_이름
    lowerThan: 더_높은_우선순위_그룹_이름
    associativity: 결합방향(left / right / none)
    assignment: 할당방향_사용(true / false)
}

Swift에 정의된 우선순위 그룹이 있음.

infix operator **: MultiplicationPrecedence
func **(lhs: String, rhs: String) -> Bool {
    return lhs.contains(rhs)
}

함수

종료되지 않는 함수

비반환 함수(메소드)는 반환 타입을 Never로 명시해준다.

func crash() -> Never {
    fatalError("CRASH!")
}
crash()	// 프로세스 종료 후 오류 보고

옵셔널

  • 옵셔널은 열거형으로 구현되어 있음! 그러므로 switch문으로 somenone인 케이스에 접근할 수 있으나 일반적을 옵셔널 바인딩 등의 방법을 활용한다.
  • 함수의 매개 변수 타입이 옵셔널이면, 매개 변수 기본값이 nil이 아니어도 함수 호출 시 그 부분에 아무런 값을 주지 않아도 nil이 들어올 것임을 알아야 한다.

구조체와 클래스

구조체를 사용해야 하나? 클래스를 사용해야 하나?

다음의 조건 중 하나 이상에 해당된다면 구조체를 사용하는 것을 권장한다.

  • 연관된 간단한 값의 집합을 캡슐화하는 것만이 목적일 때
  • 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
  • 구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때
  • 다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때

프로퍼티와 메소드

지연 저장 프로퍼티

  • 지연 저장 프로퍼티lazy stored property는 호출이 있어야 값을 초기화하며, 주로 복잡한 클래스나 구조체를 구현할 때 많이 사용된다.

    • 다중 스레드 환경에서 지연 저장 프로퍼티에 동시다발적으로 접근할 때 한 번만 초기화된다는 보장이 없다.

키 경로

  • 키 경로keyPath를 활용하여 어떤 프로퍼티의 위치만 참조할 수 있도록 할 수 있다. 키 경로를 사용하여 간접적으로 특정 타입의 어떤 프로퍼티 값을 가리켜야 할지 미리 지정해두고 사용할 수 있다.
  • 각 인스턴스의 KeyPath 서브스크립트 메소드에 키 경로를 전달하여 프로퍼티에 접근할 수 있다.
  • 키 경로를 잘 활용하면 타입 간의 의존성을 낮추는 데 많은 도움을 준다.
  • 키 경로는 타입 외부로 공개된 인스턴스 프로퍼티에 한하여 표현할 수 있다.
class Person {
    var name: String
    init(name: String) {
        self.name = name
    }
}
let person = Person(name: "presto")
let keyPath = \Person.name
person[keyPath: keyPath]	// Presto

self 프로퍼티

  • 인스턴스 메소드에서는 self가 인스턴스를 가리키지만, 타입 메소드에서는 self가 타입 그 자체를 가리킨다.

  • self 프로퍼티를 활용하여 값 타입 인스턴스 자체의 값을 치환할 수 있다.

    • 클래스의 인스턴스는 참조 타입이므로 self 프로퍼티에 다른 참조를 할당할 수 없다.
struct Level {
    var level: Int = 0
    mutating func levelUp() {
        level += 1
    }
    mutating func reset() {
        self = Level()
    }
}

타입 메소드

static 키워드를 사용하여 정의할 수 있으며, 상속 후 메소드 정의를 가능하게 하려면 class 키워드를 사용하여 정의한다.

접근 제어

설정자만 더 낮은 접근 수준을 갖도록 제한할 수 있다.

public struct SomeType {
    // 저장 프로퍼티의 접근 수준 다르게 하기. 설정자는 비공개 접근수준, 접근자는 공개 접근수준.
    public private(set) var property: Int = 0
    // 서브스크립트의 접근 수준 다르게 하기. 설정자는 내부 접근수준, 접근자는 공개 접근수준.
    public internal(set) subscript(some: Int) -> Int {
        get { return property }
        set { property += some }
    }
    // 저장 프로퍼티도 같은 방법으로 구현할 수 있다.
}

클로저

클로저는 참조 타입

자동 클로저

  • 자동 클로저는 전달 인자를 갖지 않는다.
  • 자동 클로저는 호출되었을 때 자신이 감싸고 있는 코드의 결과값을 반환한다.
  • 자동 클로저는 클로저가 호출되기 전까지 클로저 내부의 코드가 동작하지 않으므로 연산을 지연시킬 수 있다.
  • 자동 클로저 속성을 부여한 매개변수는 클로저 대신에 실행 결과를 전달인자로 받게 되며, 이것이 자동 클로저 매개변수에 전달되면 매개변수가 없는 결과 값의 타입을 반환하는 클로저로 변환해준다.
var strings = ["a", "b", "c"]
func first(_ function: @autoclosure () -> String) {
    function()
}
first(strings.removeFirst())
// strigns.removeFirst()의 결과인 a가 전달인자로 들어가며, String 값을 반환하는 매개변수가 없는 클로저로 변환해준다.

옵셔널 체이닝과 빠른종료

빠른종료

  • guard문의 조건에는 Bool 타입이 오므로, 옵셔널 바인딩의 역할을 하지 않을 때도 빠른 종료를 위해 사용할 수 있다.
  • 쉼표를 사용하여 추가 조건을 나열할 수 있으므로, AND 연산과 같은 결과를 낸다.
  • 제어문 전환 명령어를 사용해야 하므로 특정 블록 내부에 위치하지 않는다면 사용이 제한된다.

 

'Swift > 야곰의 스위프트' 카테고리의 다른 글

27장 ARC  (0) 2018.05.01
26장 where 절  (0) 2018.04.30
25장 패턴  (0) 2018.04.28
24장 타입 중첩  (0) 2018.04.28
23장 프로토콜 지향 프로그래밍  (0) 2018.04.28
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함