Eau de Cologne
[Rust] Lifetime elision 본문
다음 코드를 생각해봅시다.
-
fn ref_idx(v: &mut [i32], i: usize, j: usize) -> (&mut i32, &mut i32) {
-
assert!(i != j && i < v.len() && j < v.len());
-
let ptr = v.as_mut_ptr();
-
unsafe { (&mut *(ptr.add(i)), &mut *(ptr.add(j))) }
-
}
이후,
-
let mut v = vec![1, 2];
-
let (i, j) = ref_idx(&mut v, 0, 1);
-
let (k, s) = ref_idx(&mut v, 0, 1); // second mutable borrow
-
*i = 3;
-
*j = 4;
-
dbg!(v);
와 같은 코드를 작성하면 3번째 줄에서 2번째 mutable borrow가 일어나, 컴파일 에러가 납니다. 여기서, i
와 j
가 v
에서 borrow 되었다는걸 borrow checker가 어떻게 아는지 궁금했습니다.
결론은, lifetime elision이 일어나기 때문입니다. parameter에서 reference가 하나인 경우, 모든 parameter와 return값의 lifetime이 '_
로 설정되어서, i
와 j
가 v
에서 borrow 되었다는걸 알 수 있습니다. 가령이면, 코드를 아래와 같이 작성하면 두 번째 mutable borrow를 할 수 있습니다. (물론, 이 코드는 unsafe합니다)
-
fn ref_idx<'a, 'b> (v: &'a mut [i32], i: usize, j: usize) -> (&'b mut i32, &'b mut i32) {
-
assert!(i != j && i < v.len() && j < v.len());
-
let ptr = v.as_mut_ptr();
-
unsafe { (&mut *(ptr.add(i)), &mut *(ptr.add(j))) }
-
}
-
-
// ...
-
-
let mut v = vec![1, 2];
-
let (i, j) = ref_idx(&mut v, 0, 1);
-
let (k, s) = ref_idx(&mut v, 0, 1); // unsafe! but compiled...
-
*i = 3;
-
*j = 4;
-
dbg!(v);
'rkgk' 카테고리의 다른 글
SCPC 2024 2차 예선 풀이 (2) | 2024.07.27 |
---|---|
SCPC 2024 1차 풀이 (0) | 2024.07.06 |
FastIO 메모 (0) | 2023.05.25 |
[Working In Progress] Euler Tour Trick + LCA + HLD Template (0) | 2023.05.05 |
가성비 에라토스테네스의 체 (0) | 2023.04.27 |