B - 연산자와 기호
산술·비교·논리·비트·대입 연산자와 경로·참조·범위·제네릭 등에 쓰이는 기호의 문맥별 의미를 빠르게 확인합니다.
이 부록은 러스트 문법에서 자주 나오는 연산자와 기호를 빠르게 찾아보는 용어집입니다. 같은 기호라도 놓이는 자리에 따라 뜻이 달라지므로, 기호의 모양보다 먼저 그 기호가 어떤 문법 위치에 있는지 좁히는 것이 좋습니다. 아래 그림은 낯선 기호를 만났을 때 위치를 좁혀 가는 순서를 보여 줍니다.
Rust · symbol context · flowchart
기호 모양보다 먼저 문법 위치를 좁힌다
매크로, 패턴, 타입·바운드를 차례로 확인하고 나머지를 표현식으로 읽습니다. 경로는 독립된 다섯 번째 문맥이 아니라 이 여러 위치를 가로지르므로 ::와 qualified path를 별도 보조판에서 확인합니다.
매크로 호출·규칙인가?
ident!(...),macro_rules!안에서는!,$,=>, 반복 기호를 매크로 문법으로 읽습니다.패턴 위치인가?
match,let, 함수 매개변수에서는_,@,|,..가 값을 계산하지 않고 모양을 맞춥니다.타입·바운드 위치인가?
&T,Vec<T>,T: Trait + 'a처럼 값이 아니라 타입과 제약을 설명합니다.그 밖에는 표현식으로 읽는다
&expr,*expr,expr?, 산술·비교·호출·인덱싱처럼 값을 계산하거나 place를 가리키는지 확인합니다.
::는 네 분기를 가로지른다
crate::는 현재 크레이트, ::crate_name은 명시적 크레이트 경로, method::<T>는 표현식의 turbofish, <T as Trait>::item은 qualified path입니다.
위치를 좁힌 뒤 다음 표에서 같은 기호의 의미와 오버로드 범위를 대조합니다. 경로의 시작 규칙은 에디션에 따라 차이가 있으므로 현재 Rust에서는 crate::와 ::crate_name을 구분합니다.
먼저 매크로를 부르는 곳이나 macro_rules!의 규칙 안인지 봅니다. 그렇다면 !, $, =>, 반복 기호를 매크로 문법으로 읽습니다. 다음으로 match, let, 함수 매개변수 같은 패턴 위치인지 봅니다. 그곳에서는 _, @, |, ..가 값을 계산하지 않고 모양을 맞춥니다. 그다음 &T, Vec<T>, T: Trait + 'a처럼 값이 아니라 타입과 제약을 설명하는 타입이나 바운드 위치인지 봅니다. 셋 다 아니라면 &expr, *expr, expr?처럼 값을 계산하는 표현식으로 읽습니다. 경로의 ::는 이 네 갈래를 가로지르는 별도의 문맥이 아니라 어디에나 나올 수 있으므로 따로 확인합니다. crate::는 현재 크레이트에서, ::crate_name은 명시한 외부 크레이트에서 시작하는 경로이고, method::<T>는 표현식의 터보피시(turbofish), <T as Trait>::item은 완전 정규화 경로입니다. 경로가 시작하는 규칙은 에디션에 따라 조금 다를 수 있습니다.
부록 B: 연산자와 기호
이 부록에는 러스트 문법의 용어집이 들어 있으며, 연산자와, 그 자체로 쓰이거나 경로, 제네릭, 트레이트 바운드, 매크로, 속성, 주석, 튜플, 괄호의 문맥에서 나타나는 다른 기호들이 있습니다. 아래 표는 자주 헷갈리는 기호가 문맥마다 어떤 뜻을 가지고, 어디까지 오버로드할 수 있는지 비교한 것입니다.
Rust · symbols · semantic table
같은 기호도 문맥과 오버로드 범위가 다르다
먼저 문법 위치를 고정하고, 그 위치의 의미만 읽습니다. 한 기호의 특정 연산이 트레이트로 오버로드되더라도 타입·패턴·매크로에서 같은 모양이 자동으로 오버로드되는 것은 아닙니다.
| 기호 | 대표 문맥 | 문맥별 의미 | 오버로드 |
|---|---|---|---|
& |
&expr; &T; 참조 패턴; a & b |
빌림을 만들거나 참조 타입·참조 패턴을 나타내고, 이항 위치에서는 비트 AND를 계산합니다. | a & b만 BitAnd; 빌림·타입·패턴은 해당 없음 |
* |
a * b; *expr; *const T, *mut T |
곱셈, 역참조, 원시 포인터 타입을 위치에 따라 구분합니다. | 곱셈은 Mul; 비포인터 역참조는 Deref/DerefMut; 포인터 타입 표기는 해당 없음 |
.. |
범위 표현식; 구조체 업데이트; 튜플·구조체 패턴의 나머지 | 범위를 구성하거나 남은 필드를 채우거나, 패턴에서 나머지를 무시합니다. | 범위·rest 자체는 직접 오버로드하지 않음; 컬렉션 인덱싱은 Index/IndexMut |
! |
!expr; ident!(...); 타입 ! |
비트·논리 NOT, 매크로 호출, 반환하지 않는 never 타입이라는 서로 다른 역할입니다. | prefix NOT은 Not; 매크로 호출·never 타입은 해당 없음 |
? |
expr?; T: ?Sized; 매크로 반복 $(...)? |
계속값을 꺼내거나 residual을 호출자에게 반환하고, 암시적 Sized 바운드를 완화하거나, 매크로 반복을 0회 또는 1회로 지정합니다. |
expr?는 Try 기반이며 Result/Option이 대표적; stable 사용자 Try 구현을 오버로드 수단으로 간주하지 않음 |
_ |
패턴; 타입 추론 자리; 구조분해 discard; 숫자 리터럴 | 값을 바인딩하지 않는 wildcard, 추론할 타입 자리, 구조분해 대입 왼쪽에서 값을 버리는 자리, 읽기 쉬운 숫자 구분자로 쓰입니다. | 해당 없음 |
:: |
경로 세그먼트; method::<T>; <T as Trait>::item |
crate::는 현재 크레이트, ::crate_name은 명시적 크레이트 경로이며, 표현식의 generic 인수와 qualified path도 구분합니다. |
해당 없음 |
<...> / ::<...> |
Vec<u8>; parse::<i32>(); qualified path |
타입 위치에서는 generic 인수, 표현식에서는 turbofish, <T as Trait>에서는 연관 아이템 경로를 명확히 합니다. |
구분 기호는 해당 없음; 비교 연산자 </>로 쓰일 때는 PartialOrd |
: / + |
T: U + 'a; 타입 표기; 구조체 필드; 루프 라벨; a + b |
바운드와 라이프타임을 조합하고, 타입·필드·라벨을 구분하며, 표현식에서는 덧셈을 수행합니다. | 표현식의 +는 Add; 바운드 결합과 콜론 문법은 해당 없음 |
=> |
pat => expr; macro_rules! 규칙 |
match arm에서 패턴과 결과를, 선언형 매크로에서 matcher와 transcriber를 구분합니다. |
해당 없음 |
&
문맥 · &expr; &T; 참조 패턴; a & b
의미 · 빌림을 만들거나 참조 타입·참조 패턴을 나타내고, 이항 위치에서는 비트 AND를 계산합니다.
오버로드 · a & b만 BitAnd; 빌림·타입·패턴은 해당 없음
*
문맥 · a * b; *expr; *const T, *mut T
의미 · 곱셈, 역참조, 원시 포인터 타입을 위치에 따라 구분합니다.
오버로드 · 곱셈은 Mul; 비포인터 역참조는 Deref/DerefMut; 포인터 타입 표기는 해당 없음
..
문맥 · 범위 표현식; 구조체 업데이트; 튜플·구조체 패턴의 나머지
의미 · 범위를 구성하거나 남은 필드를 채우거나, 패턴에서 나머지를 무시합니다.
오버로드 · 범위·rest 자체는 직접 오버로드하지 않음; 컬렉션 인덱싱은 Index/IndexMut
!
문맥 · !expr; ident!(...); 타입 !
의미 · 비트·논리 NOT, 매크로 호출, 반환하지 않는 never 타입이라는 서로 다른 역할입니다.
오버로드 · prefix NOT은 Not; 매크로 호출·never 타입은 해당 없음
?
문맥 · expr?; T: ?Sized; 매크로 반복 $(...)?
의미 · 계속값을 꺼내거나 residual을 호출자에게 반환하고, 암시적 Sized 바운드를 완화하거나, 매크로 반복을 0회 또는 1회로 지정합니다.
오버로드 · expr?는 Try 기반이며 Result/Option이 대표적; stable 사용자 Try 구현을 오버로드 수단으로 간주하지 않음
_
문맥 · 패턴; 타입 추론 자리; 구조분해 discard; 숫자 리터럴
의미 · 값을 바인딩하지 않는 wildcard, 추론할 타입 자리, 구조분해 대입 왼쪽에서 값을 버리는 자리, 읽기 쉬운 숫자 구분자로 쓰입니다.
오버로드 · 해당 없음
::
문맥 · 경로 세그먼트; method::<T>; <T as Trait>::item
의미 · crate::는 현재 크레이트, ::crate_name은 명시적 크레이트 경로이며, 표현식의 generic 인수와 qualified path도 구분합니다.
오버로드 · 해당 없음
<...> / ::<...>
문맥 · Vec<u8>; parse::<i32>(); qualified path
의미 · 타입 위치에서는 generic 인수, 표현식에서는 turbofish, <T as Trait>에서는 연관 아이템 경로를 명확히 합니다.
오버로드 · 구분 기호는 해당 없음; 비교 연산자 </>로 쓰일 때는 PartialOrd
: / +
문맥 · T: U + 'a; 타입 표기; 구조체 필드; 루프 라벨; a + b
의미 · 바운드와 라이프타임을 조합하고, 타입·필드·라벨을 구분하며, 표현식에서는 덧셈을 수행합니다.
오버로드 · 표현식의 +는 Add; 바운드 결합과 콜론 문법은 해당 없음
=>
문맥 · pat => expr; macro_rules! 규칙
의미 · match arm에서 패턴과 결과를, 선언형 매크로에서 matcher와 transcriber를 구분합니다.
오버로드 · 해당 없음
오버로드가 가능한 부분만 좁혀 읽기
&, *, !, +는 특정 표현식 연산에서만 트레이트와 연결됩니다. 같은 기호의 타입·패턴·매크로 역할은 별도 문법입니다.
컴파일러 진단으로 최종 문맥 확인
기호 후보가 둘 이상이면 피연산자 타입, 기대 타입, 이름이 해석된 경로를 진단과 함께 확인해 의미를 확정합니다.
이 비교표는 본문의 전체 연산자·기호 색인을 대체하지 않습니다. 낯선 기호를 발견했을 때 어느 표와 Reference 절로 이동할지 빠르게 좁히는 판독판입니다.
&는 &expr에서 대여를 만들고, &T에서 참조 타입을, 패턴에서 참조 패턴을 나타내며, a & b처럼 이항 위치에서만 비트 AND이고 BitAnd로 오버로드할 수 있습니다. *는 곱셈, 역참조, 원시 포인터 타입을 위치에 따라 나타내며, 곱셈은 Mul, 포인터가 아닌 값의 역참조는 Deref와 DerefMut로 오버로드합니다. ..는 범위를 만들거나, 구조체 업데이트에서 남은 필드를 채우거나, 패턴에서 나머지를 무시하며, 그 자체는 오버로드하지 않고 컬렉션의 인덱싱만 Index와 IndexMut로 합니다. !는 비트와 논리 NOT, 매크로 호출, 돌아오지 않는 never 타입이라는 서로 다른 역할을 하며, 앞에 붙는 NOT만 Not으로 오버로드합니다. ?는 expr?에서 값을 꺼내거나 나머지를 호출한 쪽에 돌려주고, T: ?Sized에서 암묵적인 Sized 바운드를 완화하며, 매크로 반복에서는 0번이나 1번을 뜻합니다. expr?는 Try를 바탕으로 하지만, 안정 버전의 사용자가 Try를 구현해 오버로드하는 수단으로 보지는 않습니다. 한 기호의 어떤 연산이 트레이트로 오버로드되더라도, 타입이나 패턴, 매크로에서 같은 모양의 기호까지 오버로드되는 것은 아닙니다.
연산자
다음 표는 러스트의 연산자와, 그 연산자가 문맥에서 어떻게 나타나는지의 예, 짧은 설명, 그리고 그 연산자를 오버로드할 수 있는지를 보여 줍니다. 오버로드할 수 있는 연산자에는 오버로드하는 데 쓸 트레이트를 적었습니다.
| 연산자 | 예 | 설명 | 오버로드 |
|---|---|---|---|
! | ident!(...), ident!{...}, ident![...] | 매크로 확장 | |
! | !expr | 비트 또는 논리 보수 | Not |
!= | expr != expr | 같지 않음 비교 | PartialEq |
% | expr % expr | 산술 나머지 | Rem |
%= | var %= expr | 산술 나머지 후 대입 | RemAssign |
& | &expr, &mut expr | 대여 | |
& | &type, &mut type, &'a type, &'a mut type | 빌린 포인터 타입 | |
& | expr & expr | 비트 AND | BitAnd |
&= | var &= expr | 비트 AND 후 대입 | BitAndAssign |
&& | expr && expr | 단락 평가 논리 AND | |
* | expr * expr | 산술 곱셈 | Mul |
*= | var *= expr | 산술 곱셈 후 대입 | MulAssign |
* | *expr | 역참조 | Deref |
* | *const type, *mut type | 원시 포인터 | |
+ | trait + trait, 'a + trait | 복합 타입 제약 | |
+ | expr + expr | 산술 덧셈 | Add |
+= | var += expr | 산술 덧셈 후 대입 | AddAssign |
, | expr, expr | 인수와 원소의 구분자 | |
- | - expr | 산술 부정 | Neg |
- | expr - expr | 산술 뺄셈 | Sub |
-= | var -= expr | 산술 뺄셈 후 대입 | SubAssign |
-> | fn(...) -> type, |...| -> type | 함수와 클로저의 반환 타입 | |
. | expr.ident | 필드 접근 | |
. | expr.ident(expr, ...) | 메서드 호출 | |
. | expr.0, expr.1 등 | 튜플 인덱싱 | |
.. | .., expr.., ..expr, expr..expr | 오른쪽 끝을 포함하지 않는 범위 리터럴 | PartialOrd |
..= | ..=expr, expr..=expr | 오른쪽 끝을 포함하는 범위 리터럴 | PartialOrd |
.. | ..expr | 구조체 리터럴의 업데이트 문법 | |
.. | variant(x, ..), struct_type { x, .. } | 나머지를 무시하는 패턴 | |
... | expr...expr | (더는 쓰지 않으며, 대신 ..=를 씁니다) 패턴에서 끝을 포함하는 범위 패턴 | |
/ | expr / expr | 산술 나눗셈 | Div |
/= | var /= expr | 산술 나눗셈 후 대입 | DivAssign |
: | pat: type, ident: type | 제약 | |
: | ident: expr | 구조체 필드 초기화 | |
: | 'a: loop {...} | 루프 라벨 | |
; | expr; | 구문과 아이템의 끝 | |
; | [...; len] | 고정 크기 배열 문법의 일부 | |
<< | expr << expr | 왼쪽 시프트 | Shl |
<<= | var <<= expr | 왼쪽 시프트 후 대입 | ShlAssign |
< | expr < expr | 미만 비교 | PartialOrd |
<= | expr <= expr | 이하 비교 | PartialOrd |
= | var = expr, ident = type | 대입이나 동치 | |
== | expr == expr | 같음 비교 | PartialEq |
=> | pat => expr | match 갈래 문법의 일부 | |
> | expr > expr | 초과 비교 | PartialOrd |
>= | expr >= expr | 이상 비교 | PartialOrd |
>> | expr >> expr | 오른쪽 시프트 | Shr |
>>= | var >>= expr | 오른쪽 시프트 후 대입 | ShrAssign |
@ | ident @ pat | 패턴 바인딩 | |
^ | expr ^ expr | 비트 배타적 OR | BitXor |
^= | var ^= expr | 비트 배타적 OR 후 대입 | BitXorAssign |
| | pat | pat | 패턴의 대안 | |
| | expr | expr | 비트 OR | BitOr |
|= | var |= expr | 비트 OR 후 대입 | BitOrAssign |
|| | expr || expr | 단락 평가 논리 OR | |
? | expr? | 오류 전파 |
범위 리터럴의 PartialOrd는 범위를 오버로드한다는 뜻이 아니라, 범위의 원소 타입이 비교할 수 있어야 범위가 쓸모 있다는 뜻입니다.
비연산자 기호
다음 표들에는 연산자로 동작하지 않는 기호를 모았습니다. 이 기호들은 함수나 메서드 호출처럼 동작하지 않습니다. 먼저 그 자체로 나타나며 여러 곳에서 유효한 기호입니다.
| 기호 | 설명 |
|---|---|
'ident | 이름 붙은 라이프타임이나 루프 라벨 |
바로 뒤에 u8, i32, f64, usize 등이 붙은 숫자 | 특정 타입의 숫자 리터럴 |
"..." | 문자열 리터럴 |
r"...", r#"..."#, r##"..."## 등 | 이스케이프 문자를 처리하지 않는 원시 문자열 리터럴 |
b"..." | 바이트 문자열 리터럴로, 문자열 대신 바이트 배열을 만듭니다. |
br"...", br#"..."#, br##"..."## 등 | 원시 바이트 문자열 리터럴로, 원시 문자열과 바이트 문자열 리터럴을 합친 것입니다. |
c"..." | 끝에 널 문자가 붙는 C 문자열 리터럴 |
'...' | 문자 리터럴 |
b'...' | ASCII 바이트 리터럴 |
|...| expr | 클로저 |
! | 발산 함수에 쓰는, 언제나 비어 있는 never 타입 |
_ | 값을 바인딩하지 않는 와일드카드 패턴, 추론할 타입의 자리, 숫자 리터럴의 구분자 |
r#ident | 키워드를 식별자로 쓰는 원시 식별자 |
다음 표는 모듈 계층을 거쳐 아이템에 이르는 경로의 문맥에서 나타나는 기호입니다.
| 기호 | 설명 |
|---|---|
ident::ident | 네임스페이스 경로 |
crate::path | 현재 크레이트의 루트에서 시작하는 경로 |
::crate_name::path | 외부 프렐류드의 크레이트 이름에서 시작하는 명시적 경로 |
self::path | 현재 모듈에서 시작하는 경로, 곧 명시적인 상대 경로 |
super::path | 현재 모듈의 부모에서 시작하는 경로 |
type::ident, <type as trait>::ident | 연관 상수, 함수, 타입 |
<type>::... | 이름을 바로 붙일 수 없는 타입의 연관 아이템. 예: <&T>::..., <[T]>::... |
trait::method(...) | 메서드를 정의한 트레이트의 이름으로 메서드 호출의 모호함 없애기 |
type::method(...) | 메서드를 정의한 타입의 이름으로 메서드 호출의 모호함 없애기 |
<type as trait>::method(...) | 트레이트와 타입의 이름으로 메서드 호출의 모호함 없애기 |
다음 표는 제네릭 타입 매개변수를 쓰는 문맥에서 나타나는 기호입니다.
| 기호 | 설명 |
|---|---|
path<...> | 타입에서 제네릭 타입의 매개변수 지정하기. 예: Vec<u8> |
path::<...>, method::<...> | 표현식에서 제네릭 타입, 함수, 메서드의 매개변수 지정하기. 흔히 터보피시라고 부릅니다. 예: "42".parse::<i32>() |
fn ident<...> ... | 제네릭 함수 정의하기 |
struct ident<...> ... | 제네릭 구조체 정의하기 |
enum ident<...> ... | 제네릭 열거형 정의하기 |
impl<...> ... | 제네릭 구현 정의하기 |
for<...> type | 고차 라이프타임 바운드(higher-ranked lifetime bound) |
type<ident=type> | 연관 타입 하나 이상에 특정 값을 정한 제네릭 타입. 예: Iterator<Item=T> |
다음 표는 트레이트 바운드로 제네릭 타입 매개변수를 제약하는 문맥에서 나타나는 기호입니다.
| 기호 | 설명 |
|---|---|
T: U | 제네릭 매개변수 T가 U를 구현하는 타입으로 제약됩니다. |
T: 'a | 제네릭 타입 T는 'a보다 오래 살아야 하며, 곧 그 타입은 'a보다 짧게 사는 참조를 담을 수 없습니다. |
T: 'static | 제네릭 타입 T는 'static인 것 말고는 빌린 참조를 담지 않습니다. |
'b: 'a | 제네릭 라이프타임 'b는 'a보다 오래 살아야 합니다. |
T: ?Sized | 제네릭 타입 매개변수가 동적 크기 타입이어도 되게 합니다. |
'a + trait, trait + trait | 복합 타입 제약 |
다음 표는 매크로를 부르거나 정의하는 문맥과, 아이템에 속성을 지정하는 문맥에서 나타나는 기호입니다.
| 기호 | 설명 |
|---|---|
#[meta] | 외부 속성 |
#![meta] | 내부 속성 |
$ident | 매크로 치환 |
$ident:kind | 매크로 메타변수 |
$(...)... | 매크로 반복 |
ident!(...), ident!{...}, ident![...] | 매크로 호출 |
다음 표는 주석을 만드는 기호입니다.
| 기호 | 설명 |
|---|---|
// | 한 줄 주석 |
//! | 안쪽 한 줄 문서화 주석 |
/// | 바깥쪽 한 줄 문서화 주석 |
/*...*/ | 블록 주석 |
/*!...*/ | 안쪽 블록 문서화 주석 |
/**...*/ | 바깥쪽 블록 문서화 주석 |
다음 표는 괄호가 쓰이는 문맥입니다.
| 기호 | 설명 |
|---|---|
() | 빈 튜플(유닛이라고도 합니다). 리터럴이자 타입입니다. |
(expr) | 괄호로 묶은 표현식 |
(expr,) | 원소가 하나인 튜플 표현식 |
(type,) | 원소가 하나인 튜플 타입 |
(expr, ...) | 튜플 표현식 |
(type, ...) | 튜플 타입 |
expr(expr, ...) | 함수 호출 표현식. 튜플 구조체와 튜플 열거형 배리언트를 초기화할 때도 씁니다. |
다음 표는 중괄호가 쓰이는 문맥입니다.
| 문맥 | 설명 |
|---|---|
{...} | 블록 표현식 |
Type {...} | 구조체 리터럴 |
다음 표는 대괄호가 쓰이는 문맥입니다.
| 문맥 | 설명 |
|---|---|
[...] | 배열 리터럴 |
[expr; len] | expr의 복사본 len개를 담은 배열 리터럴 |
[type; len] | type의 인스턴스 len개를 담은 배열 타입 |
expr[expr] | 컬렉션 인덱싱으로, Index와 IndexMut로 오버로드할 수 있습니다. |
expr[..], expr[a..], expr[..b], expr[a..b] | 컬렉션 슬라이싱처럼 보이는 컬렉션 인덱싱으로, 인덱스로 Range, RangeFrom, RangeTo, RangeFull을 씁니다. |
정리
- 같은 기호도 매크로, 패턴, 타입과 바운드, 표현식 가운데 어디에 있는지에 따라 뜻이 다르므로, 먼저 문법 위치를 좁힙니다.
- 경로의
::는 어느 위치에든 나타나며,crate::,::crate_name, 터보피시::<T>, 완전 정규화 경로<T as Trait>::item을 구분합니다. +,*,&,!같은 연산자의 일부 쓰임만Add,Mul,BitAnd,Not같은 트레이트로 오버로드할 수 있으며, 대여나 타입, 패턴의 같은 기호는 오버로드되지 않습니다...는 범위, 구조체 업데이트, 나머지 패턴을,?는 오류 전파,?Sized, 매크로 반복을 문맥에 따라 나타냅니다.
연습 문제
1. 같은 기호, 다른 뜻
다음 코드의 각 &와 *는 무엇을 뜻하나요? 기호가 타입 자리에 있는지, 식 안에서 피연산자 하나 앞에 붙었는지, 두 피연산자 사이에 있는지를 보고 구분해 보세요.
fn f(x: &i32, flags: u8) -> i32 {
let y = *x * 2;
let low = flags & 0b0000_1111;
y + low as i32
}해설 보기
매개변수의 &i32는 타입 위치의 참조 타입입니다. *x의 *는 앞에 붙은 역참조이고, 그 뒤의 * 2는 이항 위치의 곱셈입니다. flags & 0b0000_1111의 &는 이항 위치의 비트 AND이며, 숫자 리터럴 안의 _는 읽기 쉽게 넣은 구분자입니다.
2. 오버로드할 수 있을까
직접 만든 Matrix 타입에 (가) a * b (나) -a (다) a && b (라) a += b를 쓰고 싶습니다. 각각 어떤 트레이트를 구현하나요?
해설 보기
(가)는 Mul, (나)는 Neg, (라)는 AddAssign을 구현하면 됩니다. (다)의 &&는 단락 평가를 하는 논리 연산자로, 오버로드할 수 있는 트레이트가 없어 직접 만든 타입에 쓸 수 없습니다. 비트 단위 AND가 필요하다면 BitAnd를 구현해 a & b로 씁니다.
다음 부록 C - 파생 가능한 트레이트에서는 derive 속성으로 자동 구현할 수 있는 트레이트를 정리합니다.