연산자 참조

연산자 참조 (Operators reference)

Elixir 연산자는 종류가 꽤 있어요. 이 문서 하나만 읽으면 Elixir가 어떤 연산자를 지원하는지, 그것들이 어떻게 해석(parse)되고, 어떻게 정의되고, 어떻게 오버라이드되는지 한눈에 알 수 있어요. 연산자의 세계를 정리된 표로 풀어볼게요.

출처: Elixir 공식 가이드

본문

이 문서는 Elixir의 연산자가 어떻게 해석되고, 어떻게 정의되고, 어떻게 오버라이드될 수 있는지에 대한 완전한 참조예요.

일반 연산자 (General operators)

Elixir는 다음의 내장 연산자들을 제공해요.

  • +- — 단항(일항) 양수/음수
  • +, -, *, / — 기본 산술 연산
  • ++-- — 리스트 연결과 차집합(뺄셈)
  • and&& — 엄격·완화 불리언 "and"
  • or|| — 엄격·완화 불리언 "or"
  • not! — 엄격·완화 불리언 "not"
  • innot in — 소속(membership) 확인
  • @ — 모듈 속성
  • .., .., ..// — 범위(range) 생성
  • <> — 바이너리 연결
  • |> — 파이프라인(pipeline)
  • =~ — 텍스트 기반 매치

이 중 상당수는 가드(guard)에서 쓸 수 있어요. 허용되는 가드 함수와 연산자 목록을 참고하세요.

추가로, Elixir가 해석은 하지만 실제로는 쓰지 않는 연산자도 몇 개 있어요. 목록과 사용 지침은 아래 "커스텀 및 오버라이드된 연산자"를 보세요.

어떤 연산자들은 특수 형식(special form)이라 오버라이드할 수 없어요.

  • ^ — 핀(pin) 연산자
  • . — 점(dot) 연산자
  • = — 매치(match) 연산자
  • & — 캡처(capture) 연산자
  • :: — 타입(type) 연산자

마지막으로, 아래 연산자들은 우선순위 표에 등장하지만 특정 구문 안에서만 의미가 있어요.

  • =>%{} 문서 참조
  • when — Guards 문서 참조
  • <-forwith 문서 참조
  • \\ — 기본 인자 문서 참조

비교 연산자 (Comparison operators)

Elixir는 다음의 내장 비교 연산자를 제공해요. 모두 가드에서 쓸 수 있어요.

  • == — 같다
  • === — 엄격히 같다
  • != — 같지 않다
  • !== — 엄격히 같지 않다
  • < — 작다
  • > — 크다
  • <= — 작거나 같다
  • >= — 크거나 같다

=====의 유일한 차이는 ===가 정수와 부동소수점을 비교할 때 엄격하다는 점이에요.

iex> 1 == 1.0
true
iex> 1 === 1.0
false

!=!==는 각각 =====의 부정으로 동작해요.

연산자 우선순위와 결합성 (Operator precedence and associativity)

다음은 Elixir가 해석할 수 있는 모든 연산자의 목록으로, 높은 우선순위부터 낮은 우선순위 순서로 나열했고, 함께 결합성(associativity)을 나타냈어요.

연산자 결합성
@ Unary
. Left
+ - ! ^ not Unary
** Left
* / Left
+ - Left
++ -- +++ --- .. <> Right
// (..// 안에서만 유효) Right
in not in Left
|> <<< >>> <<~ ~>> <~ ~> <~> Left
< > <= >= Left
== != =~ === !== Left
&& &&& and Left
|| ||| or Left
= Right
&, ... Unary
| Right
:: Right
when Right
<- \\ Left
=> (%{} 안에서만 유효) None

Elixir에는 삼항(ternary) 연산자도 두 개 있어요.

연산자 결합성
first..last//step Right
%{map | key => value, ...} None

폐기 예정인 연산자 우선순위 (Deprecated operator precedence)

Elixir는 not left in rightnot(left in right)로, !left in right!(left in right)로 해석하는데, 이는 위의 우선순위 표와 어긋나요. 이런 동작은 폐기 예정(deprecated)이라 경고를 내보내요. 두 구문 모두 left not in right로 써야 해요. 앞으로의 메이저 버전에서는 파서가 위 표와 일치하도록 바뀔 거예요.

커스텀 및 오버라이드된 연산자 (Custom and overridden operators)

Elixir는 미리 정의된 연산자 집합을 해석할 수 있어요. (일부 언어처럼) 새 연산자를 정의하는 것은 불가능해요. 하지만 Elixir가 해석할 수 있는 모든 연산자를 Elixir가 다 쓰는 건 아니에요. 예를 들어 +||는 덧셈과 불리언 or에 쓰이지만, <~>는 (유효함에도) 쓰이지 않아요.

연산자를 정의하려면 평소처럼 def* 구문(def, defp, defmacro 등)을 쓰되, 연산자가 쓰이는 방식과 비슷한 문법을 사용하면 돼요.

defmodule MyOperators do
  # ~> 는 주어진 두 숫자 중 큰 값을,
  # <~ 는 작은 값을 반환하도록 정의한다.

  def a ~> b, do: max(a, b)
  def a <~ b, do: min(a, b)
end

새로 정의한 연산자를 쓰려면 그 연산자를 정의한 모듈을 import해야 해요.

iex> import MyOperators
iex> 1 ~> 2
2
iex> 1 <~ 2
1

다음은 Elixir가 해석할 수 있지만 기본적으로는 쓰이지 않는 모든 연산자 표예요.

  • |||
  • &&&
  • <<<
  • >>>
  • <<~
  • ~>>
  • <~
  • ~>
  • <~>
  • +++
  • ---
  • ...

&&&, <<<, >>>, ||| 이 연산자들은 import했을 때 Bitwise 모듈이 사용해요. 자세한 내용은 Bitwise 문서를 참고하세요.

참고로 Elixir 커뮤니티는 일반적으로 커스텀 연산자를 권장하지 않아요. 함수처럼 설명적인 이름이 없으니 읽기도, 이해하기도 어려울 수 있거든요. 다만 특정한 경우나 커스텀 도메인 특화 언어(DSL)에서는 이런 관행이 정당화될 수 있어요.

+ 같은 미리 정의된 연산자를 대체하는 것도 가능하지만, 극히 권장되지 않아요.

더 알아보기

  • Naming conventions (이전 장)
  • Patterns and guards (다음 장)
  • Guards 문서 (Elixir 공식 문서)
  • Bitwise 모듈 문서 (Elixir 공식 문서)