아삭아삭 iOS 개발

[Swift 독학] 패스트캠퍼스 챌린지 34일차_옵셔널 체이닝(2) 본문

Swift

[Swift 독학] 패스트캠퍼스 챌린지 34일차_옵셔널 체이닝(2)

바닐라머스크 2022. 2. 26. 23:27

 

오늘은 지난 시간에 이어 옵셔널 체이닝의 다양한 사용법에 대해 알아보겠습니다.

옵셔널 반환값을 통한 서브 스크립트 접근, 여러 레벨로 체인 연결, nil 병합 연산자 그리고 강제언래핑 대체용으로의 사용방법순으로 정리해보겠습니다~ :)

 

반응형

 

■ 옵셔널 체이닝의 다양한 활용방법 8가지 (5) ~ (8)

 

5) 옵셔널 체이닝을 통해 서브 스크립트 접근하기

  • 옵셔널 체이닝을 사용하여 옵셔널 값의 서브 스크립트에서 조회, 설정, 해당 서브 스크립트 호출 성공여부 확인 가능
  • 옵셔널 타입에 서브 스크립트 접근 가능
    → 서브 스크립트가 dictionary타입의 서브 스크립트같은 옵셔널 타입의 값을 반환하는 경우,
        
    옵셔널 반환값을 연결하기 위해 서브 스크립트의 닫는 대괄호 뒤에 물음표 추가
if let firstCountryName = vanillaMusk.location?[0].name {
    print("The first country name is \(firstCountryName)")
} else {
    print("Unable to retrieve the first country name.")
}
// Unable to retrieve the first country name.
// vanillaMusk.location 프로퍼티에 country 배열의 첫번째 나라이름 조회
// 현재 vanillaMusk.location는 nil 이기 때문에 서브 스크립트 호출은 실패
// 여기서 옵셔널 체이닝이 시도되는 옵셔널 값은 vanillaMusk.location

vanillaMusk.location?[0] = Country(name: "Korea")
// 옵셔널 체이닝으로 서브 스크립트를 사용해 새로운 값 설정 가능
// location이 현재 nil이므로 서브 스크립트 설정은 실패

let vanillaMuskCountry = Location()
vanillaMuskCountry.countries.append(Country(name: "Korea"))
vanillaMuskCountry.countries.append(Country(name: "Netherlands"))
vanillaMusk.location = vanillaMuskCountry

if let firstCountryName = vanillaMusk.location?[0].name {
    print("The first country where i've lived so far is \(firstCountryName)")
} else {
    print("Unable to retrieve the first country name.")
}
// The first country where i've lived so far is Korea

/// 옵셔널 타입에 서브 스크립트 접근
var averageTariff = ["Taxi": [2000, 5000, 3400], "Bus": [1250, 800, 500]]
averageTariff["Taxi"]?[0] = 7000
averageTariff["Bus"]?[0] += 50
averageTariff["Drone"]?[0] = 250000 // nil
// ?를 활용하여 값을 설정하고, 연산하는 등에 옵셔널 체이닝 사용
// 첫번째와 두번째 호출은 성공, 세번째는 실패

 

 

6) 여러 레벨들로의 체인 연결

  • 여러 depth의 옵셔널 체이닝을 연결시 모델내 프로퍼티, 메서드, 서브 스크립트로 깊게 접근 가능
    단, 여러 depth 옵셔널 체이닝은 반환된 값에 많은 수준의 옵션성을 추가하진 않음
  • 옵셔널 체이닝으로 String 조회시, 사용된 체이닝의 수준과 무관하게 항상 String? 반환됨
  • 옵셔널 체이닝으로 String? 조회시, 사용된 체이닝의 수준과 무관하게 항상 String? 반환됨

 

if let vanillaMuskswellknownRiverName = vanillaMusk.location?.continent?.wellknownRiverName {
    print("VanillaMusk's wellknown rivername is \(vanillaMuskswellknownRiverName).")
} else {
    print("Unable to retrieve the wellknown river's name.")
}
// Unable to retrieve the wellknown river's name.
// vanillaMusk의 location 프로퍼티에 continent 프로퍼티에 wellknownRiverName 프로퍼티를 접근
// location과 wellknownRiverName 프로퍼티를 연결하기 위해 2단계 수준의 옵셔널 체인이 사용됨
// vanillaMusk.location.continent의 값이 현재 nil이므로 호출 실패
// wellknownRiverName 프로퍼티 타입은 String? 이며, vanillaMusk.location?.continent?.wellknownRiverName의 반환값은 (2단계의 옵셔널 체이닝이 프로퍼티 옵셔널 타입에 적용되었지만) 여전히 String?

let vanillaMuskLocation = Continent()
vanillaMuskLocation.continentName = "Asia"
vanillaMuskLocation.wellknownRiverName = "Han river"
vanillaMusk.location?.continent = vanillaMuskLocation

if let vanillaMuskswellknownRiverName = vanillaMusk.location?.continent?.wellknownRiverName {
    print("VanillaMusk's wellknown rivername is \(vanillaMuskswellknownRiverName).")
} else {
    print("Unable to retrieve the wellknown river's name.")
}
// VanillaMusk's wellknown rivername is Han river.

 

 

7) nil 병합 연산자(nil coalescing operator)에서의 옵셔널 체이닝 사용

  • 옵셔널 값이 nil이라면 ?? 기호 우측의 반환함
  • (x ?? y) 경우, x 값이 있으면 x값을 풀고 x nil이면 기본값인 y 반환

 

 

 

 

let defaultBrandName = "Nike"
var userDefinedBrandName: String?
var brandNameToUse = userDefinedBrandName ?? defaultBrandName
// userDefinedBrandName 변수는 기본값이 nil인 옵셔널 String으로 정의
// userDefinedBrandName ?? defaultBrandName 표현식은 defaultBrandName 또는 "Nike"의 값을 반환함

var userDefinedBrandName2 = "Under Armour"
var brandNameToUse2 = userDefinedBrandName2 ?? defaultBrandName
// userDefinedBrandName2 변수에 nil이 아닌 값 "Under Armour" 대입
// userDefinedBrandName ?? defaultBrandName 표현식은 "Under Armour"을 반환

 

 

8) 강제언래핑 대체용으로의 옵셔널 체이닝

  • (옵셔널이 nil 아닌 경우) 프로퍼티, 메서드, 서브 스크립트를 호출하려는 옵셔널 뒤에 ? 배치하여 옵셔널 체이닝 지정
     
    값에 강제 언래핑을 하기 위해 옵셔널 뒤에 ! 배치하는 것과 유사
    ※ 
    , 옵셔널이 nil 옵셔널 체이닝은 실패하지만, 강제 언래핑은 에러 발생한다는 차이점 있음
  • 옵셔널 체이닝 조회하는 프로퍼티, 메서드, 서브 스크립트가 옶셔널 값이 아닌 값을 반환하더라도 항상 옵셔널 값을 반환
     
    옵셔널 반환값으로 옵셔널 체이닝 호출 성공여부 확인 가능
        ① 
    반환된 옵셔널 체이닝에 포함됨 - 성공
        ② 
    반환된 옵셔널 값이 nil - 실패
  • 옵셔널 체이닝 호출 결과는 반환값과 동일한 타입 (, 옵셔널로 래핑됨)
    ex) String
    반환하는 프로퍼티는 옵셔널 체이닝을 통해 접근하면 String? 
class Nomad {
    var location: Location?
}

class Location {
    var nameOfCountry = "Korea"
}

// Location 인스턴스는 기본값이 "Korea"인 nameOfCountry 라는 String프로퍼티를 갖음
// Nomad 인스턴스는 Location? 타입의 옵셔널 location 프로퍼티를 갖음

let vanillaMusk = Nomad()
// 새로운 Nomad 인스턴스를 생성하면 location 프로퍼티는 옵셔널 규칙에 따라 nil로 초기화
// vanillaMusk는 nil의 location 프로퍼티 값을 갖음

let countryName = vanillaMusk.location!.nameOfCountry
//location가 nil값을 반환하므로 에러발생
//하지만 vanillaMusk.location가 nil값이 아니고 nameOfCountry에 적절한 문자를 포함한 String으로 설정하면 위 코드는 정상동작함

if let countryName = vanillaMusk.location?.nameOfCountry {
    print("VanillaMusk, a famous digital nomad nowadays, is now living in \(countryName).")
} else {
    print("Unable to know where she/he is living in now")
}
// Unable to know where she/he is living in now

// 옵셔널 체이닝은 countryName 의 값에 접근하기 위한 대안으로 제공
// swift가 옵셔널 location 프로퍼티를 "체인"하고 location이 존재하면 countryName 값을 조회하도록 함
// nameOfCountry에 접근하기 위한 시도는 실패할 수 있으므로, 옵셔널 체이닝은 String? 타입이나 "옵셔널 String"의 값 반환
// location이 nil일 경우, nameOfCountry 접근이 불가능한 사실을 반영하기 위해 옵셔널 String은 nil임
// 옵셔널 String은 언래핑한 문자에 옵셔널 바인딩으로 접근하고 countryName 문자에 옵셔널이 아닌 값을 할당

// 옵셔널 체인으로 조회 된다는 것은 nameOfCountry 호출을 항상 String대신 String?을 반환한다는 뜻

vanillaMusk.location = Location()
// 더이상 nil값을 갖기 않기 위해 vanillaMusk.location에 Location 인스턴스 할당 가능
// vanillaMusk.location는 nil이 아닌 실제 Location 인스턴스를 포함

if let countryName = vanillaMusk.location?.nameOfCountry {
    print("VanillaMusk, a famous digital nomad nowadays, is now living in \(countryName).")
} else {
    print("Unable to know where she/he is living in now")
}
// VanillaMusk, a famous digital nomad nowadays, is now living in Korea.
// 위에 한번 실행했던 동일한 옵셔널 체이닝으로 nameOfCountry에 접근하면 기본 nameOfCountry의 값"Korea"의 String?을 반환

 

이렇게 총 8가지의 옵셔널 체이닝 활용 방안에 대해 예시와 함께 알아보았습니다.

..정말 사용방법이 다양하고 많네요ㅎㅎ 잘 알아두면 유용할 것 같습니다~~ :)

 

위 사례에 쓰인 코드들은 참조 [2], [3]내 샘플들을 응용한 코드들이니, 더 상세한 설명과 명확한 예시를 알고 싶으실 경우
아래 링크 참조 부탁드립니다!

 

 

 

 

 

 

본 게시물은 개인 공부 기록용이므로 내용에 오류가 있을 수 있습니다.

 fast campus강의  참조자료

[1] https://blog.yagom.net/553/

[2] https://bbiguduk.gitbook.io/swift/language-guide-1/enumerations

[3] https://bbiguduk.gitbook.io/swift/language-guide-1/basic-operators#nil-nil-coalescing-operator

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.