Tuple 모듈
Tuple 모듈
Elixir에서 튜플은 여러 값이 담긴 고정 크기 컨테이너예요. 이 모듈은 그런 튜플을 다루기 위한 함수들을 모아 놓은 곳이죠. 튜플을 자주 만나게 되겠지만, 실제로 이 모듈의 함수를 쓸 일은 그리 많지 않아요 — 대부분의 작업은 패턴 매칭과 Kernel의 기본 함수로 해결되거든요.
본문
튜플 관련 함수 중 자주 쓰이는 몇 가지는 사실 Kernel에 들어 있어요. 다음을 기억해 두면 돼요.
elem/2- 인덱스로 튜플의 원소에 접근해요put_elem/3- 인덱스로 튜플에 값을 넣어요tuple_size/1- 튜플의 원소 개수를 구해요
튜플은 여러 원소를 담는 고정 크기 컨테이너로 설계됐어요. 원소를 자유롭게 추가하고 제거해야 하는 컬렉션이라면 리스트를 쓰는 게 맞아요. 그래서 Enum 함수는 튜플에서는 동작하지 않아요.
튜플은 중괄호로 표현해요.
iex> {}
{}
iex> {1, :two, "three"}
{1, :two, "three"}
튜플은 서로 다른 타입의 원소를 담을 수 있고, 메모리에서는 연속된 공간에 저장돼요. 그래서 특정 원소에 접근하는 데 걸리는 시간은 언제나 일정한 반면(상수 시간), 튜플을 수정하는 일은 얕은 복사(shallow copy)를 만들기 때문에 원소 개수에 비례해서 시간이 걸려요. 데이터를 읽는 용도라면 튜플이 좋고, 끝까지 순회해야 한다면 리스트가 더 유리해요.
튜플은 주로 두 가지 상황에서 쓰여요. 하나는 함수가 여러 값을 반환할 때이고, 다른 하나는 에러 처리를 할 때예요. 예를 들어 File.read/1은 파일 읽기에 성공하면 {:ok, contents}를, 대상 파일이 없다든가 하는 이유로 실패하면 {:error, reason}을 반환해요.
이 모듈에 있는 원소 추가·제거 함수들은 실제로는 좀처럼 쓰이지 않아요. 튜플을 컬렉션처럼 다루겠다는 뜻이 되거든요. 튜플에 원소를 추가해야 한다면, 패턴 매칭으로 기존 튜플의 원소를 꺼낸 뒤 새로운 튜플을 만드는 편이 낫다는 게 Elixir의 권장 방식이에요.
tuple = {:ok, :example}
# 비추천
result = Tuple.insert_at(tuple, 2, %{})
# 권장
{:ok, atom} = tuple
result = {:ok, atom, %{}}
delete_at(tuple, index)
지정한 인덱스의 원소를 튜플에서 제거해요.
@spec delete_at(tuple(), non_neg_integer()) :: tuple()
tuple에서 index 위치에 있는 원소를 지워요. index가 음수이거나 tuple의 길이보다 크거나 같으면 ArgumentError를 던져요. 인덱스는 0부터 시작해요. 이 함수는 컴파일러가 인라인 처리해요.
iex> tuple = {:foo, :bar, :baz}
iex> Tuple.delete_at(tuple, 0)
{:bar, :baz}
duplicate(data, size)
새 튜플을 만들어요.
@spec duplicate(term(), non_neg_integer()) :: tuple()
주어진 data를 모든 위치에 담은, 크기가 size인 튜플을 만들어요. 컴파일러가 인라인 처리해요.
iex> Tuple.duplicate(:hello, 3)
{:hello, :hello, :hello}
insert_at(tuple, index, value)
튜플에 원소를 삽입해요.
@spec insert_at(tuple(), non_neg_integer(), term()) :: tuple()
value를 tuple의 index 위치에 넣어요. index가 음수이거나 tuple의 길이보다 크면 ArgumentError를 던져요. 인덱스는 0부터 시작해요. 컴파일러가 인라인 처리해요.
iex> tuple = {:bar, :baz}
iex> Tuple.insert_at(tuple, 0, :foo)
{:foo, :bar, :baz}
iex> Tuple.insert_at(tuple, 2, :bong)
{:bar, :baz, :bong}
product(tuple) (since 1.12.0)
튜플 원소들의 곱을 계산해요.
@spec product(tuple()) :: number()
빈 튜플 {}의 곱은 1로 정의돼요.
iex> Tuple.product({255, 255})
65025
iex> Tuple.product({255, 1.0})
255.0
iex> Tuple.product({})
1
sum(tuple) (since 1.12.0)
튜플 원소들의 합을 계산해요.
@spec sum(tuple()) :: number()
빈 튜플 {}의 합은 0으로 정의돼요.
iex> Tuple.sum({255, 255})
510
iex> Tuple.sum({255, 0.0})
255.0
iex> Tuple.sum({})
0
to_list(tuple)
튜플을 리스트로 변환해요.
@spec to_list(tuple()) :: list()
튜플의 모든 원소를 담은 새 리스트를 반환해요. 컴파일러가 인라인 처리해요.
iex> tuple = {:foo, :bar, :baz}
iex> Tuple.to_list(tuple)
[:foo, :bar, :baz]