스위프트에는 세 가지 기본 표준 컬렉션이 있습니다: Array, Set 및 Dictionary. 각 컬렉션은 서로 다른 인터페이스를 구현하며, 내부 구조가 다르고 서로 다른 작업을 위해 설계되었습니다.
문제의 배경:
스위프트에서는 컬렉션이 타입 안전성(type safety) 및 성능을 염두에 두고 설계되었으며, Arrays/Set/Dictionary에 대해 Copy-on-Write 원칙에 따른 값 의미론(value semantics) 및 복사가 포함됩니다.
문제:
초보 개발자는 종종 Array만 사용하여 Set 또는 Dictionary를 사용해야 하는 상황에서도 이를 사용하는 경향이 있어 메모리 낭비 및 접근/검색 속도 저하로 이어집니다. 차이를 이해해야 합니다.
해결책:
인덱스를 통한 접근이 가능한 순서가 있는 요소의 컬렉션으로, 중복이 가능합니다. 일반적으로 동적 버퍼를 통해 구현됩니다.
유일한 요소(훌륭한 해시 가능 타입)의 순서가 없는 컬렉션입니다. 해시를 통한 접근이 매우 빠르며 중복을 허용하지 않습니다.
키-값 쌍의 컬렉션입니다. 키는 해시 가능해야 합니다. 해시 테이블을 통해 키로 값을 접근할 수 있습니다.
코드 예시:
var arr: [Int] = [1, 2, 3, 4] var set: Set<Int> = [1, 2, 2, 3] var dict: [String: Int] = ["a": 1, "b": 2] // set == [1, 2, 3] — 중복이 제거됨
주요 특징:
Set이나 Dictionary에서 non-Hashable 타입을 사용할 수 있나요?
아니요. Set/Dictionary에 저장하려면 요소가 해시 가능해야 합니다(고유한 해시 식별자를 가져야 함). 그렇지 않으면 컴파일러가 컬렉션 생성을 허용하지 않습니다.
struct Point {} // Set<Point>는 오류를 발생시킵니다, 왜냐하면 Point는 해시 가능하지 않기 때문입니다.
Set의 요소 저장 순서가 추가한 순서와 같습니까?
아니요. Set는 순서를 보장하지 않으며, 반복(iteration)은 아무 순서로 실행될 수 있습니다. 순서가 필요하다면 Array를 사용하십시오.
존재하지 않는 키에 접근하려고 할 때 Dictionary에서 무슨 일이 발생합니까?
Dictionary는 Optional을 반환합니다. 주의하십시오 — 존재하지 않는 키로 접근하려고 하면 nil을 반환하고 오류를 발생시키지 않습니다.
let val = dict["not exist"] // val은 nil
개발자가 고유 사용자 목록을 위해 Array를 사용하고 contains를 통해 고유성을 검사합니다. 큰 목록에서는 많은 검사가 필요하여 시간이 많이 소요됩니다.
장점:
단점:
같은 목록이 Set으로 구현됩니다. 존재 여부 확인이 즉각적이며, 고유한 값이 보장됩니다.
장점:
단점: