14: Optionals

그루두·2024년 4월 23일
0

100 days of SwiftUI

목록 보기
22/108

100 days of swiftui: 14
https://www.hackingwithswift.com/100/swiftui/14

optional

값을 지닐 수도 있고 안 지닐 수도 있는 타입이다. 예로 아래 sentence는 String 값을 지닐 수도 있고 값이 없는 nil일 수도 있다.

let sentence: String?

nil"", [], 0처럼 초기화된 값이나 빈 String, 배열, 0이 아니다. 그래서 optional을 의미하는 String?String은 다르다. 그러므로 optinal은 non-optional 값처럼 사용할 수 없고, unwrap 과정을 거쳐 non-optional로 변경한 후 사용할 수 있다.

예:

var number: Int? = nil
number = 30
//if number > 10 {
//    print("\(number) is bigger than 10. (1)")
//}
if let number = number {
    if number > 10 {
        print("\(number) is bigger than 10. (2)")
    }
} else {
    print("number is unwrapped.")
}
//if number > 10 {
//    print("\(number) is bigger than 10. (3)")
//}

주석 처리한 코드는 swift가 안정성을 위해 실행하지 않는다.

  • if let을 통해 unwrap할 수 있다.
  • 조건문의 안에서만 non-optional한 값을 사용할 수 있다.
  • if let을 사용할 때 일반적으로 같은 이름의 상수에 unwrap한다.
  • optional이 non-optional을 unwrap할 수 없다.
  • optional과 non-optional을 비교할 수 없다.

코드 파일
https://github.com/soaringwave/Ios-studying/commit/568d625600847b581ae98e95ebabd779874a21e0

guard

if let 말고도 guard도 unwrap할 때 사용할 수 있다.

func checkStringHasValue(textInput: String?) {
    guard let textInput = textInput else {
        print("There is no text.")
        return
    }
    
    print("'\(textInput)' is input.")
}

checkStringHasValue(textInput: nil)
checkStringHasValue(textInput: "")

결과:

There is no text.
'' is input.

위 예시에서 알 수 있듯이 guardif let과 달리 아래 두 특징이 있다.

  • 함수 안에서 입력값의 존재여부를 확인한다면, 만약 값이 없을 땐 return을 작성해야 한다.
  • else {}에 입력값이 없는 경우의 코드를 작성하고, 값이 있는 경우는 조건문 이후 이용할 수 있다.

nil coalescing

dictionary의 default처럼, 값이 없는 경우를 대비해 미리 값을 지정할 수도 있다. [optional의 데이터] ?? [optional의 데이터가 nil일 경우 대체할 값]을 입력하면 된다.

예:

struct Computer {
    var user: String?
    var model: String
}

var computer1 = Computer(user: "user1", model: "macbook pro 1")
var computer2 = Computer(user: nil, model: "macbook pro 2")
let user2 = computer2.user ?? "unknown"
print(user2)

결과:

unknown

❗️ nil coalescing도 같은 타입으로 설정해야 한다. 아래 예시는 String?과 Int를 사용해서 안된다.

let tempString: String? = "example"
let tempExample = tempString ?? 0

코드 파일
https://github.com/soaringwave/Ios-studying/commit/3aac475a5503fabc0de2d5149aa80b2029083b77

optional changing

// 1
let credentials = ["twostraws", "fr0sties"]
let lowercaseUsername = credentials.first.lowercased()

// 2
let songs: [String]? = [String]()
let finalSong = songs.last.count

// 3
let capitals = ["Scotland": "Edinburgh", "Wales": "Cardiff"]
let scottishCapital = capitals["Scotland"].uppercased()

위 코드는 모두 swift에서 에러가 나는 코드다.

  • 1의 경우엔 credentials이 빈 배열이라서 credentials.first가 없을 수도 있는데 lowercased()를 사용한다.
  • 2의 경우엔 songsnil일 수도 있고 마찬가지로 songs.last가 존재하지 않을 수도 있는데 count를 사용한다.
  • 3의 경우엔 capitals["Scotland"]가 존재하지 않을 수 있는데 uppercased()를 사용한다.

이 코드처럼 존재하지 않는 값을 참조할 때를 대비해서, '값이 존재한다면 뒤를 실행해줘'인 optional changing ?를 사용하면 된다.

// 1
let credentials = ["twostraws", "fr0sties"]
let lowercaseUsername = credentials.first?.lowercased()

// 2
let songs: [String]? = [String]()
let finalSong = songs?.last?.count

// 3
let capitals = ["Scotland": "Edinburgh", "Wales": "Cardiff"]
let scottishCapital = capitals["Scotland"]?.uppercased()
struct Book {
    var title: String
    var author: String?
}

let book1: Book? = nil
let authorOfBook1 = book1?.author?.first?.uppercased() ?? "U"
print(authorOfBook1)

코드 파일
https://github.com/soaringwave/Ios-studying/commit/1f4d338fb71639c1e8273adfb663832502fca7e3

optional try

throwtry?를 활용해서 에러를 관리할 수 있다고 이해했다. 지금 당장 코드를 직관적으로 이해하기도 어렵고 동작원리도 이해하기 어려워서 다시 공부해야겠다.

https://www.hackingwithswift.com/quick-start/beginners/how-to-handle-function-failure-with-optionals

profile
계속 해보자

0개의 댓글

관련 채용 정보