[Swift] 문법 감 살리기

승민·2025년 3월 5일

Swift

목록 보기
1/10
post-thumbnail

Swift 를 다시 접했을 때, 이전 내용을 되살리는 시간이에요.
이미 학습한 사람들을 대상으로 간단히 다시 돌아보는 것이 목적이에요.

Nill-Coalescing 연산자

a != nil ? a! : b

예제

let defaultColorName = "red"
var userDefinedColorName: String?   // defaults to nil

var colorNameToUse = userDefinedColorName ?? defaultColorName

Collection Types

Swift의 Collection Types는 데이터를 저장하고 관리하는 데 사용되는 주요 자료 구조로, Array, Set, Dictionary 세 가지가 있습니다.

예제 코드

import Foundation

// 1. Array: 순서가 있는 컬렉션
func demonstrateArray() {
    print("=== Array 예제 ===")
    var fruits: [String] = ["Apple", "Banana", "Orange"]
    
    // 순서 유지 및 인덱스 접근
    print("원래 배열: \(fruits)")
    print("첫 번째 과일: \(fruits[0])")
    
    // 요소 추가
    fruits.append("Grape")
    print("요소 추가 후: \(fruits)")
    
    // 요소 제거
    fruits.remove(at: 1)
    print("인덱스 1 제거 후: \(fruits)")
}

// 2. Set: 중복되지 않는 순서 없는 컬렉션
func demonstrateSet() {
    print("\n=== Set 예제 ===")
    var uniqueNumbers: Set<Int> = [1, 2, 3, 3, 4]
    
    // 중복 제거 확인
    print("Set 내용: \(uniqueNumbers)") // 3이 한 번만 출력됨
    
    // 요소 추가
    uniqueNumbers.insert(5)
    print("5 추가 후: \(uniqueNumbers)")
    
    // 특정 요소 포함 여부 확인
    let containsThree = uniqueNumbers.contains(3)
    print("3 포함 여부: \(containsThree)")
}

// 3. Dictionary: 키-값 쌍으로 저장되는 컬렉션
func demonstrateDictionary() {
    print("\n=== Dictionary 예제 ===")
    var scores: [String: Int] = ["Alice": 95, "Bob": 87, "Charlie": 92]
    
    // 키를 통한 값 접근
    print("원래 딕셔너리: \(scores)")
    print("Alice의 점수: \(scores["Alice"] ?? 0)")
    
    // 값 추가 및 수정
    scores["David"] = 88
    scores["Bob"] = 90
    print("수정 후 딕셔너리: \(scores)")
    
    // 키-값 쌍 제거
    scores.removeValue(forKey: "Charlie")
    print("Charlie 제거 후: \(scores)")
}

// 실행
demonstrateArray()
demonstrateSet()
demonstrateDictionary()

출력 결과

=== Array 예제 ===
원래 배열: ["Apple", "Banana", "Orange"]
첫 번째 과일: Apple
요소 추가 후: ["Apple", "Banana", "Orange", "Grape"]
인덱스 1 제거 후: ["Apple", "Orange", "Grape"]

=== Set 예제 ===
Set 내용: [1, 2, 3, 4]
5 추가 후: [1, 2, 3, 4, 5]
3 포함 여부: true

=== Dictionary 예제 ===
원래 딕셔너리: ["Bob": 87, "Alice": 95, "Charlie": 92]
Alice의 점수: 95
수정 후 딕셔너리: ["Bob": 90, "Alice": 95, "Charlie": 92, "David": 88]
Charlie 제거 후: ["Bob": 90, "Alice": 95, "David": 88]

각 Collection Type의 특징 설명

  1. Array

    • 특징: 순서가 유지되며, 동일한 타입의 요소를 인덱스를 통해 접근할 수 있는 컬렉션입니다.
    • 예제에서 확인한 점:
      • fruits[0]으로 첫 번째 요소에 접근 가능 (순서 보장).
      • append로 요소 추가, remove(at:)로 특정 인덱스 제거 가능.
    • 사용 시나리오: 순서가 중요한 리스트(예: 작업 목록, 순위표)를 다룰 때 유용.
  2. Set

    • 특징: 중복된 요소를 허용하지 않고, 순서가 없는 컬렉션입니다. 요소의 고유성을 보장합니다.
    • 예제에서 확인한 점:
      • [1, 2, 3, 3, 4]에서 3이 한 번만 출력됨 (중복 제거).
      • insert로 요소 추가, contains로 특정 요소 존재 여부 확인 가능.
    • 사용 시나리오: 고유한 값 집합(예: 태그, ID 목록)을 관리할 때 적합.
  3. Dictionary

    • 특징: 키-값 쌍으로 데이터를 저장하며, 키를 통해 값에 접근합니다. 키는 고유해야 합니다.
    • 예제에서 확인한 점:
      • scores["Alice"]로 특정 키의 값 접근.
      • 새로운 키-값 쌍 추가("David": 88) 및 기존 값 수정("Bob": 90) 가능.
      • removeValue(forKey:)로 특정 키-값 쌍 제거.
    • 사용 시나리오: 이름과 점수, ID와 정보 등 연관된 데이터를 매핑할 때 유용.

요약

  • Array: 순서가 중요하고 중복 허용.
  • Set: 순서 없고 중복 불가.
  • Dictionary: 키-값 쌍으로 데이터 관리.

Function

Swift는 함수형 프로그래밍 패러다임을 지원하는 언어로, 함수형 언어의 주요 특징을 잘 보여줄 수 있습니다. 함수형 언어의 핵심 특징은 다음과 같습니다:

  1. 불변성(Immutability): 데이터가 한 번 정의되면 변경되지 않음.
  2. 일급 함수(First-Class Functions): 함수를 변수처럼 다룰 수 있음.
  3. 고차 함수(Higher-Order Functions): 함수가 다른 함수를 인자로 받거나 반환할 수 있음.
  4. 순수 함수(Pure Functions): 동일한 입력에 대해 항상 동일한 출력을 반환하며 부작용이 없음.
  5. 재귀(Recursion): 반복 대신 재귀를 활용해 문제를 해결.

이제 Swift로 위 특징을 보여주는 예제를 만들고 설명하겠습니다.


예제 코드: 숫자 리스트 필터링 및 변환

// 1. 불변성(Immutability)을 위한 상수 사용
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// 2. 일급 함수(First-Class Functions): 함수를 변수에 저장
let isEven: (Int) -> Bool = { $0 % 2 == 0 }

// 3. 고차 함수(Higher-Order Functions): filter와 map 사용
let evenNumbers = numbers.filter(isEven) // 짝수만 필터링
let squaredEvens = evenNumbers.map { $0 * $0 } // 짝수를 제곱

// 4. 순수 함수(Pure Functions): 부작용 없는 계산
func add(_ a: Int, _ b: Int) -> Int {
    return a + b // 입력이 같으면 항상 동일한 출력
}

// 5. 재귀(Recursion): 리스트의 합을 구하는 함수
func sumOfList(_ list: [Int], accumulator: Int = 0) -> Int {
    if list.isEmpty {
        return accumulator
    }
    return sumOfList(Array(list.dropFirst()), accumulator: accumulator + list.first!)
}

// 결과 출력
print("원본 리스트: \(numbers)")          // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print("짝수 리스트: \(evenNumbers)")      // [2, 4, 6, 8, 10]
print("짝수의 제곱: \(squaredEvens)")    // [4, 16, 36, 64, 100]
print("리스트 합: \(sumOfList(numbers))") // 55
print("순수 함수 예시: \(add(3, 5))")     // 8

코드 설명: 함수형 특징과 연결

  1. 불변성(Immutability)

    • let numbers로 리스트를 상수로 정의해 한 번 생성된 후 변경되지 않도록 했습니다. 함수형 언어에서는 변수를 var로 바꾸는 대신 새로운 값을 생성하는 방식을 선호합니다.
  2. 일급 함수(First-Class Functions)

    • isEven은 짝수를 판별하는 함수를 변수처럼 정의한 예입니다. Swift에서는 함수를 값처럼 다룰 수 있어 변수에 저장하거나 전달할 수 있습니다.
  3. 고차 함수(Higher-Order Functions)

    • filtermap은 Swift의 대표적인 고차 함수입니다.
      • filter(isEven)isEven 함수를 받아 짝수만 걸러냅니다.
      • map { $0 * $0 }은 각 요소를 제곱한 새로운 리스트를 반환합니다.
    • 고차 함수는 로직을 추상화해 코드 재사용성을 높입니다.
  4. 순수 함수(Pure Functions)

    • add 함수는 외부 상태에 의존하지 않고, 동일한 입력 (3, 5)에 대해 항상 8을 반환합니다. 부작용(side effect)이 없다는 점이 함수형 프로그래밍의 핵심입니다.
  5. 재귀(Recursion)

    • sumOfListfor 루프 대신 재귀를 사용해 리스트의 합을 계산합니다.
      • 리스트가 비었으면 누적값을 반환하고, 그렇지 않으면 첫 번째 요소를 더한 뒤 나머지 리스트로 재귀 호출합니다.
    • 함수형 언어에서는 재귀가 반복문을 대체하는 일반적인 패턴입니다.

함수형 프로그래밍의 장점

  • 예측 가능성: 순수 함수와 불변성 덕분에 코드 동작을 예측하기 쉽습니다.
  • 간결함: 고차 함수와 재귀로 복잡한 로직을 간단히 표현할 수 있습니다.
  • 안전성: 상태 변이(mutation)가 없어 멀티스레드 환경에서 충돌 위험이 줄어듭니다.

코드로 감 살리기

Open API 활용해보기

  • 아래 링크를 통해 JSON 값 가져와보기
    • https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=<API_Key_Value>&targetDt=20250304

  • https://jsonviewer.stack.hu/
    • 위 링크로 JSON 값 변환

0개의 댓글