순서대로 값을 보관하려면 Array, 키로 조회하려면 Map, 중복을 없애려면 Set을 고르세요. 컴프리헨션으로 값을 걸러 변환하고 새 컬렉션을 만들 수 있습니다.
첫 프로그램을 따라 토파즈를 설치하세요. 배열과 반복문은 데이터와 제어에서 먼저 익힐 수 있습니다.
점수를 거르고 없는 위치 조회하기
작업 폴더에 다음 코드를 collections-comprehensions.tpz로 저장하세요.
let 점수들 = [10, 25, 10]
let 레이블들 = map { "Ada": 10, "Lin": 25 }
let 고유값들 = set { 10, 25, 10 }
let 집중값들 = [ for 점수 in 점수들 if 점수 >= 20 => 점수 * 2 ]
let 첫값 = 점수들[0]
let 누락 = 점수들.get(9)
let 에이다포함 = "Ada" in 레이블들.keys
let 누락표시 = match 누락 {
case Some(값) => "found {값}"
case None => "missing"
}
print("{점수들}:{고유값들.toArray()}:{레이블들.keys}")
print("{집중값들}:{첫값}:{에이다포함}")
print(누락표시)같은 폴더에서 파일을 검사하고 실행하세요.
topaz check collections-comprehensions.tpz
topaz run collections-comprehensions.tpz검사는 종료 코드 0으로 성공합니다. 실행하면 다음 결과를 출력합니다.
[10, 25, 10]:[10, 25]:[Ada, Lin]
[50]:10:true
missing입력에서 결과까지 따라가기
배열은 [10, 25, 10]을 유지합니다. 집합은 처음 넣은 순서대로 [10, 25]를 남깁니다. 맵은 "Ada"에 10, "Lin"에 25를 연결합니다. keys 배열도 이 삽입 순서를 유지합니다.
집중값들에 넣는 식이 컴프리헨션입니다. 각 점수를 읽고 20 이상인 값을 골라 두 배로 만듭니다. 이 입력에서는 25가 조건을 통과해 50이 되므로 결과는 [50]입니다.
| 필요한 작업 | 선택 | 순서와 중복 |
|---|---|---|
| 위치로 값 읽기 | Array<T> | 인덱스가 증가하는 순서, 중복 유지 |
| 키로 값 읽기 | Map<K, V> | 키를 삽입한 순서 |
| 서로 다른 값 보관하기 | Set<T> | 각 값을 처음 삽입한 순서 |
컬렉션 읽기와 변경
점수들[0]은 10을 읽습니다. 직접 인덱스로 읽을 때 음수나 범위 밖 인덱스를 쓰면 실행 오류가 납니다. 해당 위치가 없을 수 있다면 점수들.get(9)를 쓰세요. 이 호출은 None을 반환하므로 예제는 missing을 출력합니다. 값이 있으면 get은 Some(값)을 반환합니다. 이 두 경우를 표현하는 타입이 Option입니다.
컬렉션 자체를 바꾸려면 push 같은 변경 메서드를 부르기 전에 뿌리 바인딩을 let mut로 선언하세요. 변경할 수 없는 바인딩도 새 컬렉션을 만드는 식의 입력으로 쓸 수 있습니다.
맵을 만들 때는 키를 중복해서 쓸 수 없습니다. 같은 리터럴 키를 반복하면 정적 오류가 납니다. 실행 중 키가 같아지면 원본의 모든 피연산자를 성공적으로 계산한 뒤 실행 오류가 납니다. 키 추가나 값 변경이 목적이면 insert를 쓰세요.
기존 맵의 값을 바꿔도 키 순서는 유지됩니다. 맵 항목이나 집합 요소를 삭제하면 해당 위치도 사라집니다. 다시 넣으면 맨 뒤에 붙습니다.
리터럴·반복문·컴프리헨션 고르기
- 항목을 직접 적으려면
[a, b],set { a, b },map { key: value }를 쓰세요. - 여러 단계를 수행하려면
for item in source { ... }를 쓰세요. 문장으로 쓰면 출력 같은 동작을 수행합니다. 식으로 쓰면 본문 결과를Array에 모읍니다. - 필터링과 변환에는
[ for item in source if condition => result ]를 쓰세요. 집합은set { for item in source => result }, 맵은map { for item in source => key: value }로 만듭니다.
컴프리헨션은 for로 시작합니다. 추가 for나 if 절은 쉼표 없이 연결하고 => 뒤에 결과를 적으세요. 각 절은 왼쪽부터 차례로 중첩됩니다. 실행한 모든 절과 본문 계산이 성공하면 결과 컬렉션을 사용할 수 있습니다.
조회와 리터럴 고치기
맵의 키를 찾으려면 "Ada" in 레이블들.keys를 쓰세요. "Ada" in 레이블들은 쓸 수 없습니다.
배열 타입에는 [T] 대신 Array<T>를 쓰세요. 집합은 set, 맵은 map으로 시작합니다. { key: value }는 구조적 레코드를 만듭니다. 맵을 만들지는 않습니다. #{...}는 잘못된 문법입니다.
collections-comprehensions.tpz의 점수들.get(9)를 점수들[9]로 바꾸면 인덱스 범위 오류로 실행이 멈춥니다. 값이 없을 수 있다면 get을 유지하세요. 직접 읽으려면 인덱스를 먼저 고치세요.
컴프리헨션의 패턴은 도달한 각 항목과 일치해야 합니다. 일치하지 않으면 실행 오류가 납니다. 뒤의 패턴으로 값을 꺼내기 전에 if 절로 원하지 않는 항목을 거르세요.
다른 컬렉션 규칙
- 배열 스프레드는 다른
Array를 받습니다. 집합·맵 리터럴과 컴프리헨션에는 스프레드 문법이 없습니다. - 빈
set {}과map {}에는 기대 타입Set<T>나Map<K, V>가 필요합니다. - 맵 키와 집합 요소는 키 비교를 지원해야 합니다. 복합 값은 내부 구성 요소도 모두 이를 지원해야 합니다. 이 성질을 키 사용 가능성이라고 합니다.
for는 배열·정수 범위·집합·map.keys를 정해진 순서로 읽습니다. 문자열은 스칼라 연산으로 유니코드 스칼라 값을 꺼내세요.- 사용자 정의 순회·제너레이터·지연 또는 병렬 컴프리헨션·임의 순회 값의 스프레드·순서 없는 컬렉션은 지원하지 않습니다.
순회 중 값에 이름을 붙이는 방법은 패턴과 제어 흐름을 참고하세요. 사용할 수 있는 메서드는 컬렉션 연산에 있습니다.