A type that represents either a wrapped value or nil, the absence of a value
Optional에 대해 더 알고 싶다면...
*Xcode에서 Optional
문자를 키보드의option
+ mouse click
시 Optional에 대한 애플 공식 문서를 볼 수 있다.
출처: [애플 공식문서: Optional] https://developer.apple.com/documentation/swift/optional
Optional의 다양한 상태
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value.
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
/// Creates an instance that stores the given value.
있음 과 없음의 개념
nil
을 바라볼 때 0값이 들어있다라고 생각하고 값이 없다라고 단정 지을 수 있다.
하지만 0도 값이다. 0이라는 값이 들어있는 것이다.
nil
은 값이 아예 없는 것이다.
ㄴ 따라서 제대로 처리를 하지 않으면 무엇이든 들어갈 수도 있고 예상하지 않았던 것들이 nil
을 침범할 수 있다.
Optional이 왜 필요한가?
책상에 비유 해서 생각하면 공간 하나하나 필요한 물품으로 채워져 있고 특정 자리에는 아무것도 없는 빈 공간이 있다고 가정해 보자. 그 공간에 접근 했을 때 왜 오류가 나는가?
: 컴퓨터 속 메모리를 주관하는 관리자는 무자비하기 때문에.
운영체제 커널
이 RAM
을 포함한 메모리를 관리하게 된다.
운영체제 커널
이 RAM
의 할당량을 지정 해 준다.
*운영체제가 특정한 프로그램에 자리를 하나 할당 한다고 가정하자. 그럼 그 프로그램이 종료되고 자리를 반납할 시 그 프로그램이 존재 했던 곳은 완벽하게 비어
있는 공간이 아니게
된다.
*이 상황에서 빈공간 임에도 불구하고 다른 프로그램이 이 공간을 침범하게 되면 RAM
은 그 프로그램을 강제로 죽이게되고 그 결과로 프로그램이 crash
된다.
Optional & Memory
var yagom: String = "yagom"
// 이 곳을 비울 수 없다. 무조건 값이 있어야 한다.
let integer: Int = 42
let shortForm: Int? = 42
let emptybox: Int? = nil
// shortForm은 존재하는 공간에 더불어 보호막을 가지고 있다.
// 스위프트는 빈공간을 허용하지 않는다. 대신 optional이란 곳에 nil을 넣게 되면 우린 거기에 마치 빈 상자라는 값을 넣는 것과 같다. 그리고 이 보호막은 메모리를 또한 차지한다.
// shortForm은 integer에 42라는 숫자값과 더불어 보호막 때문에 조금 더 많은 메모리가 할당된다.
// 따라서 그냥 int보다는 공간이 더 필요하다.
// 더 많은 메모리를 차지하게 되기에 조금 더 비효율적이게 된다.
// shortForm은 비교적 확실성이 떨어지기도 한다. 따라서 optional은 최소화 하는 것이 좋다.
let longForm: Optional<Int> = Int("42")
// 컴퓨터는 longForm의 값이 nil이 나올지 42가 나올지 실행하기 전에는 확인할 수가 없다.
// 따라서 Optional값으로 지정해 줘서 해당 값에 문제가 있을지 없을지 보호장치를 설정 해 놓아야 한다.
Dictionary & Optional
let videoPaths = ["star": "/glyphs/star.png"]
if let path: String = videoPaths["star"] {
print("path: ", path)
} else {
print("path 없음")
}
// Dictionary 결과값은 항상 optional타입이다.
// ㄴ 사전에 특정 단어의 뜻이 있을 수도 없을 수도 있기 때문이다.
// 따라서 Dictionary의 값을 사용하려면 Optional Binding을 활용해서 변환 해 주어야 한다.
set
을 활용한 배열 내 중복 요소 제거func isCheckedOverlap(userInput: [Int]) -> Bool {
let nonRepeatingNumbers = Set(userInput)
if nonRepeatingNumbers.count == 3 {
return true
} else {
return false
}
}
*array
를 set
으로 변환 시켜주면 중복된 값이 제거 된다.
set
으로 변환 시 배열 내 요소들의 순서가 뒤죽박죽 섞이게 된다. index값이 중요한 경우 이 방식은 최선의 방법이 아닌듯 싶다.continue
의 활용법for number in 0...9 {
if number % 2 == 0 {
continue
}
print(number) // 결과 : 1, 3, 5, 7, 9
}
*continue
를 맞닥드리게되면 "무시하고 밑으로 내려가세요" 가 아니라 "continue
를 만났으니 다시 위로 돌아가서 반복 이어서 계속하세요" 라고 이해하면 된다.
break
의 활용법for num in 0...8 {
if num % 2 == 0 {
break
}
print(num)
}
반복문
또는 switch
문에서 사용된다종료
시키는 역할을 가진다.switch
구문에서는 특정한 case
를 충종할 때 종료하게 하는 역할어떻게 하면 간결함
과 가독성
두 마리 토끼를 다 잡을 수 있을까 고민하였다.
메소드를 최대한 잘게 세부화
시키고 애플 공식문서를 토대로 메소드명을 수정하는 방향으로 작업하다보니 그래도 나름 간결하면서도 가독성이 좋은 코드를 설계할 수 있었던 것 같다. 위 그림은 @Fezz와 저의 자랑스러운 설계도입니다. Fezz가 엄청 예쁘게 만들어 줬어요~🤩