Swift (옵셔널 체이닝, Queue , Stack , Set , Overloading)

옵셔널 체이닝

Swift 언어에서 옵셔널 값을 안전하게 참조하고 호출하는 방법을 제공하는 기능

옵셔널 체이닝을 사용하면 옵셔널 값이 nil인지 확인하고, nil 이 아닐 경우에만 해당 값에 접근하거나 메서드를 호출한다. 이를 통해 nil 로 인한 런타임 에러를 방지하고 안전하게 코드를 작성할 수 있다.

옵셔널 체이닝은 다음과 같이 ? 연산자를 사용하여 구현된다.

optionalValue?.property
optionalValue?.method()

여기서 optionalValue 는 옵셔널 타입을 가진 변수나 상수를 나타낸다.

만약 optionalValue 가 nil 이 아닌 경우에만 속성이나 메서드에 접근하거나 호출된다.

만약 nil 일 경우엔 옵셔널 체이닝 표현식 전체가 nil 을 반환하게 된다.

let result = optionalValue?.property1?.property2?.method()

위 코드에서는 optionalValue가 nil이 아닌 경우에만 property1 에 접근하고 , 그 결과가 nil 이 아닌 경우에만 property2 에 접근하고, 그 결과가 nil 이 아닌 경우에만 method() 를 호출합니다.

optionalValue?.method()  // optionalValue가 nil이 아닌 경우에만 method() 를 호출

if let result = optionalValue?.method() {
	print("Result: \\(result)")
} else { 
	print("optionalValue is nil.")
}

또한 옵셔널 체이닝은 조건문과 결합하여 사용할 수 있다. 예를 들어 옵셔널 체이닝을 사용하여 옵셔널 값이 nil 인 경우에만 특정 동작을 수행할 수 있다.

Queue 와 Stack은 데이터를 저장하는데 사용되는 추상적인 자료 구조이다.

이 두가지는 데이터를 저장하는 방식과 데이터에 접근하는 방식에서 차이가 있다.

Queue

FIFO (First-In-First-Out) 방식으로 동작한다. (먼저 추가된 요소가 먼저 제거되는 방식)

  • Enqueue (인큐) : 큐의 끝에 요소를 추가
  • Dequeue (디큐) : 큐의 맨 앞에서 요소를 제거

Stack

LIFO (Last-In-First-Out) 방식으로 동작한다. ( 나중에 추가된 요소가 먼저 제거되는 방식)

  • Push : 스택의 맨 위에 요소를 추가한다.
  • Pop: 스택의 맨 위에서 요소를 제거한다.

Queue와 Stack의 차이점

  • 데이터 접근 방식 : 큐는 맨 앞에서 요소를 제거하고 맨 뒤에서 요소를 추가한다. 스택은 맨 위에서 요소를 제거하고 맨 위에서 요소를 추가한다.
  • 동작 방식 : 큐는 FIFO 방식을 따르고 스택은 LIFO 방식을 따른다.
  • 활용 예시 : 큐는 대기열, 스케줄링, 네트워크 버퍼 등 사용되며, 스택은 함수 호출 추척, 역추적, 문서 뷰어의 뒤로가기 등에 사용될 수 있다.

sort() , sorted() 의 차이점

Array의 메서드 중 sort()메서드와 sorted() 메서드는 배열의 요소를 정렬하는데 사용된다. 하지만 두 메서드는 원본 배열에 대한 차이가 있다.

  • sort()는 원본 배열의 요소를 정렬하고 정렬된 결과를 원본 배열에 반영한다. 즉 본 배열의 순서를 변경한다.
var number = [3, 1, 4, 2]
number.sort() // [1, 2, 3, 4]
  • sorted() 는 원본 배열을 변경하지 않고 정렬된 새로운 배열을 반환한다.
let numbers = [3, 1, 4, 2]
let sortedNumbers = numbers.sorted() // [ 1, 2, 3, 4 ]

따라서 두 메서드의 가장 큰 차이점은 원본 배열의 변경 여부이다.

Set

Set는 Array와 유사하지만, 중복된 요소를 허용하지 않는다는 점에서 다르다.

var numberSet: Set<Int> = [1, 2, 3, 4, 5]

또한, 요소가 없는 빈 Set을 생성할 수도 있다.

var emptySet = Set<String>()
  • 중복 요소가 없다 : Set은 동일한 값이 여러번 추가되더라도 각 값은 한번만 저장된다.
  • 순서가 없다 : Set은 요소의 순서를 유지하지 않는다. 따라서 요소의 추가 순서와는 관계없이 저장된다.
  • 집합 연산 : Set은 합집합, 교집합, 차집합 등의 집합 연산을 제공한다.

Overloading

오버로딩은 같은 이름을 가진 다수의 함수 또는 메서드를 정의하는 것을 말한다.

이런 함수 혹은 메서드는 매개변수의 갯수나 타입이 서로 다르지만 이름이 같다.

  • 같은 범위 내에서만 함수나 메서드를 오버로딩 할 수 있다. 따라서 동일한 범위 내에서 같은 이름의 함수나 메서드를 정의할 수 없다.
  • 함수나 메서드의 시그니처가 달라야한다. 매개변수 타입이나 개수가 다르거나, 반환 타입이 다른 경우에만 오버로딩이 가능하다.
  • 오버로딩된 함수나 메서드는 리턴 타입만 다르고 매개변수의 갯수와 타입이 동일한 경우에는 허용되지 않는다.
func add(_ a: Int, _ b: Int) -> Int {
	return a + b
}

func add(_ a: Double, _ b: Double) -> Double {
	return a + b
}

func add(_ a: String, _ b: String) -> String {
	return a + b
}

위의 예시에서 add 함수는 세번 정의되었는데, 각각은 매개변수의 타입이나 반환 타입이 다르다.

이렇게 하면 같은 이름의 함수를 사용하여 서로 다른 타입의 값을 처리할 수 있다.