Feb 26, 2021, TIL (Today I Learned) - optional, continue, break

Inwoo Hwang·2021년 8월 26일
0
post-thumbnail

수업 학습내용


옵셔널이란?


값의 부재:

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
        }
    }

*arrayset으로 변환 시켜주면 중복된 값이 제거 된다.

  • 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를 충종할 때 종료하게 하는 역할

문제점 / 고민한 점


어떻게 하면 간결함가독성 두 마리 토끼를 다 잡을 수 있을까 고민하였다.

해결 방법


baseballgame-structure

메소드를 최대한 잘게 세부화 시키고 애플 공식문서를 토대로 메소드명을 수정하는 방향으로 작업하다보니 그래도 나름 간결하면서도 가독성이 좋은 코드를 설계할 수 있었던 것 같다. 위 그림은 @Fezz와 저의 자랑스러운 설계도입니다. Fezz가 엄청 예쁘게 만들어 줬어요~🤩

profile
james, the enthusiastic developer

0개의 댓글