[Rust] 1.56.0 & 2021 에디션 업데이트 발표 (번역)

https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html

우리 러스트 팀은 새 버전 [1.56.0]을 발표하게 돼서 정말 기쁩니다! 그리고 Rust 2021 또한 안정화됩니다!
러스트는 누구든 믿음직하고 효과적인 소프트웨어를 만들 수 있게 도와주는 끝내주는 언어입니다.

만약 rustup을 통해서 Rust의 이전버전을 설치해놓은 상대라면, 업데이트는 아주 쉽습니다. 그냥 이렇게 치면 돼요.
rustup update stable

rustup을 설치한 적이 없다면, 우리 웹사이트의 설치 페이지에서 받을 수 있습니다. 그리고 깃허브에서 이번 버전에 대한 릴리즈 노트를 참조해보세요.




1.56.0엔 무엇이 있나요?



Rust 2021

우리는 5월에 Rust 2021 Edition의 계획에 대해 썼습니다. 에디션은 이전 버전과의 호환성 위험을 초래할 수 있는 opt-in 변경을 위한 메커니즘입니다.

이를 달성하는 방법에 대한 자세한 내용은 에디션 가이드를 참조하세요.
이번 버전은 특히 2018년 버전에 비해 더 작습니다. 하지만 기존 코드의 일부 코너 케이스를 깨뜨리는 것을 피하기 위해 버전 opt-in이 필요한 멋진 변경 사항이 일부 있습니다.

각각의 새로운 기능과 마이그레이션 지침에 대한 자세한 내용은 아래 에디션 가이드의 새로운 장을 참조하십시오.

Disjoint capture:
클로저는 이제 항상 전체 식별자를 캡처하는 대신 개별로 명명된 필드를 캡처합니다.

IntoIterator for arrays:
array.into_iter()는 이제 참조 대신 값으로 항목을 반복합니다.

macro-ruls의 or 패턴이 이제 top-level A|B in :pat와 일치합니다.

Default Cargo feature resolver는 이제 버전이 2입니다.

prelude에 추가된 것들:
TryInto, TryFrom 및 FromIterator는 이제 기본적으로 범위에 포함됩니다.

이제 panic 매크로는 println!()과 동일한 format 문자열을 기대합니다.

예약된 신택스: ident#, ident"...", and ident'...'

오류로 승격된 경고들
bare_trait_objects
ellipsis_inclusive_range_patterns.




Disjoint capture in closures

클로저는 body에 사용되는 식별자에 대한 값이나 참조를 자동으로 캡처하지만 2021년 이전에는 항상 전체적으로 캡처되었습니다.
새로운 disjoint-capture 기능은 클로저 작성 방식을 단순화할 것입니다.
간단한 예를 살펴보겠습니다.

// 2015 or 2018 edition code** **
**let a = SomeStruct::new(); **


**// 구조체의 한 필드를 밖으로 이동 ******
**drop(a.x); **


**// Ok: 여전히 다른 필드는 사용 가능. ******
**println!("{}", a.y); **


// Error: 2021 edition 이전에서는, a의 전체 캡처를 시도함.****
**let c = || println!("{}", a.y); **
c();

이 문제를 해결하려면 "let y = &a.y;"와 같이 클로저 사용 이전에 수동으로 캡처 제한 처리를 했어야 했습니다.

하지만 Rust 2021부터는 클로저가 사용하는 필드만 자동으로 캡처하므로 위의 예제는 잘 컴파일됩니다!

이 새로운 동작은 필드가 삭제되는 순서를 변경할 수 있으므로 새 버전에서만 활성화됩니다.
모든 에디션 변경 사항에 대해 자동 마이그레이션을 사용할 수 있으며, let _ = &a;를 삽입하여 클로저를 업데이트합니다.
그렇게 클로저 내부에서 전체 구조체가 이전과 같이 캡처되도록 합니다.




Migrating to 2021

이 가이드에는 모든 새로운 기능에 대한 마이그레이션 지침과 일반적으로 기존 프로젝트를 새 버전으로 전환하는 방법이 포함되어 있습니다.

많은 경우 cargo fix를 통해 필요한 변경을 자동화할 수 있습니다. 2021 에디션도 코드를 전혀 변경할 필요가 없어요!

이 에디션은 표면적으로는 작지만 여전히 많은 기여자들의 많은 노력의 산물입니다.
축하 및 감사에 대한 tracker를 확인하세요!




Cargo rust-version

Cargo.toml은 이제 crate에 대해 지원되는 최소 Rust 버전을 지정하기 위해 [package] rust-version 필드를 지원하며, 만족하지 않으면 Cargo는 조기 오류와 함께 종료됩니다.

이것은 현재 dependency resolver에게 영향을 미치지 않지만, 아이디어는 호환성 문제가 cryptic 컴파일러 오류로 바뀌기 전에 파악하는 것입니다.




binding @ 패턴에서의 새 바인딩

패턴 매칭은 전체 값을 바인딩하는 단일 식별자로 작성될 수 있으며, 그 뒤에 @ 및 더 세련된 구조화 패턴이 옵니다.
하지만 이것은 지금까지 해당 패턴에 추가 바인딩을 허용하지 않았습니다. 지금까지는요!

**struct Matrix { **
** data: Vec, **
** row_len: usize, **
**} **


// 이전에는 바인딩할 별도의 문이 필요했습니다.
// 전체 구조체와 해당 부분도 읽습니다.****
let matrix = get_matrix(); **
let row_len = matrix.row_len; **
// 비구조화 패턴

**let Matrix { row_len, .. } = matrix; **


// Rust 1.56에서는 저걸 한번에 처리할 수 있어요!****
**let matrix @ Matrix { row_len, .. } = get_matrix(); **

이건 실제로 Rust 1.0 이전에 허용되었지만 당시 알려진 unsoundness로 인해 제거되었습니다.
그 이후로 borrow checker가 발전하고 과중한 테스트를 거쳐, 컴파일러 팀은 이것이 stable Rust에서 사용하는 것이 안전하다고 결정했어요!




Stable이 된 API들

다음 메서드와 트레잇 구현들이 stable이 되었습니다.

std::os::unix::fs::chroot
UnsafeCell::raw_get
BufWriter::into_parts
core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe} (이전에는 std에만 존재)
Vec::shrink_to
String::shrink_to
OsString::shrink_to
PathBuf::shrink_to
BinaryHeap::shrink_to
VecDeque::shrink_to
HashMap::shrink_to
HashSet::shrink_to

다음의 함수들은 이제 const가 됩니다.

std::mem::transmute
[T]::first
[T]::split_first
[T]::last
[T]::split_last




기타 변경점

1.56 릴리즈에는 이외의 기타 변경점들도 있습니다. RustCargoClippy에서 무엇이 바뀌었는지 확인해보세요.




1.56.0의 컨트리뷰터들

1.56의 완성엔 수많은 사람들이 함께했습니다. 전부 여러분이 없었다면 불가능했을 거에요.
고마워요!