Rust: 차용 λ²”μœ„κ°€ 항상 μ–΄νœ˜μ μ΄μ–΄μ„œλŠ” μ•ˆ λ©λ‹ˆλ‹€.

에 λ§Œλ“  2013λ…„ 05μ›” 10일  Β·  44μ½”λ©˜νŠΈ  Β·  좜처: rust-lang/rust

if ν…ŒμŠ€νŠΈμ—μ„œ λ³€κ²½ λΆˆκ°€λŠ₯ν•˜κ²Œ μ°¨μš©ν•˜λŠ” 경우 μ°¨μš©μ€ 전체 if ν‘œν˜„μ‹μ— λŒ€ν•΄ μ§€μ†λ©λ‹ˆλ‹€. μ΄λŠ” μ ˆμ—μ„œ λ³€κ²½ κ°€λŠ₯ν•œ 차용으둜 인해 차용 검사기가 μ‹€νŒ¨ν•¨μ„ μ˜λ―Έν•©λ‹ˆλ‹€.

μ΄λŠ” match ν‘œν˜„μ‹μ—μ„œ μ°¨μš©ν•˜κ³  νŒ” 쀑 ν•˜λ‚˜μ—μ„œ κ°€λ³€ 차용이 ν•„μš”ν•œ κ²½μš°μ—λ„ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

κ°€μž₯ κ°€κΉŒμš΄ μœ„μͺ½ @mut κ°€ κ³ μ •λ˜λ„λ‘ ν•˜λŠ” ifκ°€ μƒμžλ₯Ό 빌린 예λ₯Ό 보렀면 μ—¬κΈ°λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€. 그런 λ‹€μŒ κ°€λ³€μ μœΌλ‘œ μ°¨μš©ν•΄μ•Ό ν•˜λŠ” remove_child() κ°€ μΆ©λŒν•©λ‹ˆλ‹€.

https://github.com/mozilla/servo/blob/master/src/servo/layout/box_builder.rs#L387 -L411

@Wyverald의 μ—…λ°μ΄νŠΈλœ 예

fn main() {
    let mut vec = vec!();

    match vec.first() {
        None => vec.push(5),
        Some(v) => unreachable!(),
    }
}
A-borrow-checker NLL-fixed-by-NLL

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

아직 야간에 μ μ€‘λ˜μ§€λŠ” μ•Šμ•˜μ§€λ§Œ 이것이 이제 μ»΄νŒŒμΌλœλ‹€κ³  λ§ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

#![feature(nll)]

fn main() {
    let mut vec = vec!();

    match vec.first() {
        None => vec.push(5),
        Some(v) => unreachable!(),
    }
}

λͺ¨λ“  44 λŒ“κΈ€

생산 μ€€λΉ„λ₯Ό μœ„ν•œ 지λͺ…

λ‚˜λŠ” 이것을 잘 μ •μ˜λ˜κ±°λ‚˜ 이전 버전과 ν˜Έν™˜λœλ‹€κ³  λΆ€λ₯Ό κ²ƒμž…λ‹ˆλ‹€.

μ½”λ“œκ°€ μž¬κ΅¬μ„±λ˜μ—ˆμ§€λ§Œ λ‹€μŒμ€ λ‚΄κ°€ μˆ˜ν–‰ν•΄μ•Ό ν•˜λŠ” 빌림 κ²€μ‚¬κΈ°μ˜ ꡬ체적인 νšŒμœ μž…λ‹ˆλ‹€.

https://github.com/metajack/servo/commit/5324cabbf8757fa68b1aa36548b992041be94ef9

https://github.com/metajack/servo/commit/7234635aa580c8a821003882e77d8e043d247687

μ•½κ°„μ˜ ν† λ‘  후에, μ—¬κΈ°μ„œ μ§„μ§œ λ¬Έμ œλŠ” 차용 검사기가 별칭을 μΆ”μ ν•˜κΈ° μœ„ν•΄ λ…Έλ ₯ν•˜μ§€ μ•Šκ³  차용이 λ²”μœ„λ₯Ό λ²—μ–΄λ‚  λ•Œλ₯Ό κ²°μ •ν•˜κΈ° μœ„ν•΄ 항상 지역 μ‹œμŠ€ν…œμ— μ˜μ‘΄ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. λ‚˜λŠ” 이것을 λ³€κ²½ν•˜κΈ°λ₯Ό κΊΌλ €ν•©λ‹ˆλ‹€. 적어도 λ‹¨κΈ°μ μœΌλ‘œλŠ” 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€. μ™œλƒν•˜λ©΄ λ¨Όμ € ν•΄κ²°ν•˜κ³  싢은 λ‹€λ₯Έ λ§Žμ€ λ―Έν•΄κ²° λ¬Έμ œκ°€ 있고 λͺ¨λ“  변경은 차용 검사기에 μƒλ‹Ήν•œ μˆ˜μ •μ΄ 될 것이기 λ•Œλ¬Έμž…λ‹ˆλ‹€. λ‹€λ₯Έ κ΄€λ ¨ μ˜ˆμ™€ λ‹€μ†Œ μžμ„Έν•œ μ„€λͺ…은 문제 #6613을 μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

무슨 일이 μΌμ–΄λ‚˜κ³  μžˆλŠ”μ§€ 더 λͺ…ν™•ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό κ°œμ„ ν•  수 μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€. μ–΄νœ˜ λ²”μœ„λŠ” 비ꡐ적 μ΄ν•΄ν•˜κΈ° μ‰½μ§€λ§Œ, λ‚΄κ°€ μš°μ—°νžˆ λ°œκ²¬ν•œ 이 문제의 μ˜ˆμ—μ„œ 무슨 일이 μΌμ–΄λ‚˜κ³  μžˆλŠ”μ§€ κ²°μ½” λΆ„λͺ…ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

μ΄μ •ν‘œ/지λͺ…을 μ œκ±°ν•˜λŠ” 버그일 λΏμž…λ‹ˆλ‹€.

λ¨Ό 미래의 μ΄μ •ν‘œλ‘œ 받아듀여짐

λΆ„λ₯˜ λ²”ν”„

이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” κ°€μž₯ 쒋은 방법에 λŒ€ν•΄ λͺ‡ 가지 생각을 ν–ˆμŠ΅λ‹ˆλ‹€. λ‚΄ κΈ°λ³Έ κ³„νšμ€ 값이 "μ΄μŠ€μΌ€μ΄ν”„"ν•  λ•Œμ˜ κ°œλ…μ„ κ°–λŠ” κ²ƒμž…λ‹ˆλ‹€. κ·Έ κ°œλ…μ„ κ³΅μ‹ν™”ν•˜λ €λ©΄ μ•½κ°„μ˜ μž‘μ—…μ΄ ν•„μš”ν•©λ‹ˆλ‹€. 기본적으둜 빌린 포인터가 μƒμ„±λ˜λ©΄ 이 포인터가 νƒˆμΆœν–ˆλŠ”μ§€ μΆ”μ ν•©λ‹ˆλ‹€. 포인터가 μ£½μ—ˆμ„ λ•Œ 포인터가 μ΄μŠ€μΌ€μ΄ν”„λ˜μ§€ μ•Šμ€ 경우 μ΄λŠ” λŒ€μΆœμ„ μ’…λ£Œν•˜λŠ” κ²ƒμœΌλ‘œ 간주될 수 μžˆμŠ΅λ‹ˆλ‹€. 이 κΈ°λ³Έ μ•„μ΄λ””μ–΄λŠ” "let p = &...; use-pa-bit-but-never-again; expect-loan-to-be-expired-here;"와 같은 경우λ₯Ό λ‹€λ£Ήλ‹ˆλ‹€. λΆ„μ„μ˜ μΌλΆ€λŠ” 빌린 포인터λ₯Ό ν¬ν•¨ν•˜λŠ” λ°˜ν™˜ 값이 아직 μ΄μŠ€μΌ€μ΄ν”„λ˜μ§€ μ•Šμ€ κ²ƒμœΌλ‘œ 간주될 수 μžˆλŠ” 경우λ₯Ό λ‚˜νƒ€λ‚΄λŠ” κ·œμΉ™μ΄ 될 κ²ƒμž…λ‹ˆλ‹€. 이것은 "match table.find(...) { ... None => { expect-table-not-to-be-loaned-here; } }"와 같은 경우λ₯Ό λ‹€λ£Ήλ‹ˆλ‹€.

이 λͺ¨λ“  κ²ƒμ˜ κ°€μž₯ ν₯미둜운 뢀뢄은 λ¬Όλ‘  μ΄μŠ€μΌ€μ΄ν”„ κ·œμΉ™μž…λ‹ˆλ‹€. κ·œμΉ™μ€ ν•¨μˆ˜μ˜ ν˜•μ‹μ  μ •μ˜λ₯Ό κ³ λ €ν•΄μ•Ό ν•˜κ³  특히 수λͺ…이 μ œκ³΅ν•˜λŠ” 지식을 ν™œμš©ν•΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λŒ€λΆ€λΆ„μ˜ μ΄μŠ€μΌ€μ΄ν”„ 뢄석은 foo(p) 와 같은 ν˜ΈμΆœμ„ λ³Ό 경우 μ΄μŠ€μΌ€μ΄ν”„ p 포인터λ₯Ό κ³ λ €ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ°˜λ“œμ‹œ κ·Έλ ‡κ²Œ ν•  ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€. ν•¨μˆ˜κ°€ λ‹€μŒκ³Ό 같이 μ„ μ–Έλœ 경우:

fn foo<'a>(x: &'a T) { ... }

그러면 μ‹€μ œλ‘œ foo κ°€ a 수λͺ…보닀 더 였래 p λ₯Ό μœ μ§€ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것을 μ•Œκ³  μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ bar 와 같은 ν•¨μˆ˜λŠ” μ΄μŠ€μΌ€μ΄ν”„ 처리둜 κ°„μ£Όλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

fn bar<'a>(x: &'a T, y: &mut &'a T)

λ”°λΌμ„œ μ•„λ§ˆλ„ μ΄μŠ€μΌ€μ΄ν”„ κ·œμΉ™μ€ λ°”μΈλ”©λœ 수λͺ…이 λ³€κ²½ κ°€λŠ₯ν•œ μœ„μΉ˜μ— λ‚˜νƒ€λ‚˜λŠ”μ§€ μ—¬λΆ€λ₯Ό κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€. 이것은 사싀상 μœ ν˜• 기반 별칭 λΆ„μ„μ˜ ν•œ ν˜•νƒœμž…λ‹ˆλ‹€. λΉ„μŠ·ν•œ 좔둠이 ν•¨μˆ˜ λ°˜ν™˜ 값에도 μ μš©λœλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λ”°λΌμ„œ find λŠ” μ΄μŠ€μΌ€μ΄ν”„λ˜μ§€ μ•Šμ€ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” κ²ƒμœΌλ‘œ κ°„μ£Όλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

fn find<'a>(&'a self, k: &K) -> Option<&'a V>

κ·Έ μ΄μœ λŠ” 'a κ°€ find 에 λ°”μΈλ”©λ˜μ–΄ 있기 λ•Œλ¬Έμ— 'a Self λ˜λŠ” K μœ ν˜• λ§€κ°œλ³€μˆ˜μ— λ‚˜νƒ€λ‚  수 μ—†κΈ° λ•Œλ¬Έμ— κ°€λŠ₯ν•˜λ‹€λŠ” 것을 μ•Œκ³  μžˆμŠ΅λ‹ˆλ‹€. t 그것듀에 μ €μž₯되며, λ³€κ²½ κ°€λŠ₯ν•œ μœ„μΉ˜μ—λŠ” λ‚˜νƒ€λ‚˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. (였늘 μ‚¬μš©λ˜λŠ” 것과 λ™μΌν•œ μΆ”λ‘  μ•Œκ³ λ¦¬μ¦˜μ„ μ μš©ν•  수 있으며 수λͺ…이 λ³€κ²½ κ°€λŠ₯ν•œ μœ„μΉ˜μ— λ‚˜νƒ€λ‚˜λŠ”μ§€ μ—¬λΆ€λ₯Ό μ•Œλ €μ£ΌλŠ” #3598 μˆ˜μ •μ˜ μΌλΆ€λ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.)

이에 λŒ€ν•΄ μƒκ°ν•˜λŠ” 또 λ‹€λ₯Έ 방법은 λŒ€μΆœμ΄ _μ‘°κΈ°_ 만료된 것이 μ•„λ‹ˆλΌ λŒ€μΆœμ˜ λ²”μœ„κ°€ (일반적으둜) 전체 수λͺ…이 μ•„λ‹ˆλΌ 빌린 _λ³€μˆ˜_와 μ—°κ²°λ˜μ–΄ μ‹œμž‘λ˜κ³  λ³€μˆ˜κ°€ λ‹€μŒκ³Ό 같은 κ²½μš°μ—λ§Œ 전체 수λͺ…μœΌλ‘œ μŠΉκ²©λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. _νƒˆμΆœ_.

μž¬μ°¨μž…μ€ μ•½κ°„μ˜ ν•©λ³‘μ¦μ΄μ§€λ§Œ λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ λΉŒλ¦¬λŠ” 것은 빌린 ν¬μΈν„°μ˜ λ‚΄μš©μ„ 빌릴 λ•Œμž…λ‹ˆλ‹€. μ»΄νŒŒμΌλŸ¬κ°€ 거의 λͺ¨λ“  λ©”μ„œλ“œ ν˜ΈμΆœμ— 이λ₯Ό μžλ™μœΌλ‘œ μ‚½μž…ν•˜κΈ° λ•Œλ¬Έμ— _항상_ λ°œμƒν•©λ‹ˆλ‹€. 빌린 포인터 let p = &v 와 let q = &*p 와 같은 μž¬λΉŒλ“œλ₯Ό κ³ λ €ν•˜μ‹­μ‹œμ˜€. q 이 μ£½μ—ˆμ„ λ•Œ p λ‹€μ‹œ μ‚¬μš©ν•  수 있으면 쒋을 κ²ƒμž…λ‹ˆλ‹€. 그리고 p 와 q κ°€ λͺ¨λ‘ μ£½μ—ˆλ‹€λ©΄ λ‹€μŒμ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. v λ‹€μ‹œ( p λ˜λŠ” q μ΄μŠ€μΌ€μ΄ν”„κ°€ μ—†λ‹€κ³  κ°€μ •). 여기에 ν•©λ³‘μ¦μ΄μžˆλŠ” κ²½μš°μ΄λ‹€ q νƒˆμΆœ, p 의 수λͺ…κΉŒμ§€ νƒˆμΆœμ„ κ³ λ €ν•΄μ•Όν•©λ‹ˆλ‹€ q λ§Œλ£Œλ©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ‚˜λŠ” 이것이 μš°λ¦¬κ°€ 였늘 μ²˜λ¦¬ν•˜λŠ” 방법을 μžμ—°μŠ€λŸ½κ²Œ _somewhat_을 λ‚΄λ¦¬λŠ” 생각 : 즉, 컴파일러 λ…ΈνŠΈκ°€ q 빌린λ₯Ό p μž…λ‹ˆλ‹€ (μ²˜μŒμ—) 수λͺ… "Q"(λŒ€ν•œ, λ³€μˆ˜ 자체의) 그리고 q κ°€ μ΄μŠ€μΌ€μ΄ν”„λ˜μ–΄μ•Ό ν•˜λŠ” 경우 전체 μ–΄νœ˜ 수λͺ…μœΌλ‘œ μŠΉκ²©λ©λ‹ˆλ‹€. λ‚˜λŠ” 데이터 νλ¦„μ—μ„œ κΉŒλ‹€λ‘œμš΄ 뢀뢄이 킬을 μ‚½μž…ν•  μœ„μΉ˜λ₯Ό μ•Œκ³  μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λ‹€μ‹œ 빌릴 경우 p κ°€ 죽으면 p λŒ€ν•œ 킬을 μ¦‰μ‹œ μ‚½μž…ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 였 κΈ€μŽ„, λ‚˜λŠ” 이것에 더 λ§Žμ€ μ‹œκ°„μ„ λ‚­λΉ„ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. 그것은 κ°€λŠ₯ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€. 그리고 μ΅œμ•…μ˜ 경우 일반적인 상황에 μ ν•©ν•œ 더 κ°„λ‹¨ν•œ μ†”λ£¨μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€(예: p κ°€ 평생 λ™μ•ˆ νƒˆμΆœν–ˆλ‹€κ³  μƒκ°ν•˜μ‹­μ‹œμ˜€. of q , q λŒ€μΆœ νƒˆμΆœ 여뢀에 관계없이).

μ–΄μ¨Œλ“  더 λ§Žμ€ 생각이 ν•„μš”ν•˜μ§€λ§Œ 이것이 μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ 보기 μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” μ—¬μ „νžˆ #2202와 #8624κ°€ μˆ˜μ •λ  λ•ŒκΉŒμ§€ 이와 같은 ν™•μž₯을 μ‹œμž‘ν•˜λŠ” 것을 κΊΌλ €ν•˜λŠ”λ°, μ΄λŠ” λ°”λ‘œ 차용의 두 가지 μ•Œλ €μ§„ λ¬Έμ œμž…λ‹ˆλ‹€. λ˜ν•œ μ‹œμŠ€ν…œμ„ ν™•μž₯ν•˜κΈ° 전에 건전성 증λͺ…에 λŒ€ν•΄ 더 λ§Žμ€ 진전을 이루고 μ‹ΆμŠ΅λ‹ˆλ‹€. νƒ€μž„λΌμΈμ— μžˆλŠ” λ‹€λ₯Έ ν™•μž₯μžλŠ” #6268μž…λ‹ˆλ‹€.

이 버그에 κ±Έλ Έλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λ‚΄ μ‚¬μš© 사둀 및 ν•΄κ²° 방법:

https://gist.github.com/toffaletti/6770126

λ‹€μŒμ€ 이 λ²„κ·Έμ˜ 또 λ‹€λ₯Έ μ˜ˆμž…λ‹ˆλ‹€(제 μƒκ°μ—λŠ”).

use std::util;

enum List<T> {
    Cons(T, ~List<T>),
    Nil
}

fn find_mut<'a,T>(prev: &'a mut ~List<T>, pred: |&T| -> bool) -> Option<&'a mut ~List<T>> {
    match prev {
        &~Cons(ref x, _) if pred(x) => {}, // NB: can't return Some(prev) here
        &~Cons(_, ref mut rs) => return find_mut(rs, pred),
        &~Nil => return None
    };
    return Some(prev)
}

λ‚˜λŠ” μ“°κ³  μ‹Άλ‹€:

fn find_mut<'a,T>(prev: &'a mut ~List<T>, pred: |&T| -> bool) -> Option<&'a mut ~List<T>> {
    match prev {
        &~Cons(ref x, _) if pred(x) => return Some(prev),
        &~Cons(_, ref mut rs) => return find_mut(rs, pred),
        &~Nil => return None
    }
}

x μ°¨μž…μ€ μš°λ¦¬κ°€ μˆ μ–΄ 평가λ₯Ό 마치자 마자 μ‚¬λΌμ§€μ§€λ§Œ λ¬Όλ‘  μ§€κΈˆμ€ μ°¨μž…μ΄ 전체 μΌμΉ˜μ— λŒ€ν•΄ ν™•μž₯λœλ‹€λŠ” μΆ”λ‘ μž…λ‹ˆλ‹€.

λ‚˜λŠ” 이것을 μ–΄λ–»κ²Œ 코딩할지에 λŒ€ν•΄ 더 λ§Žμ€ 생각을 ν–ˆλ‹€. λ‚΄ κΈ°λ³Έ κ³„νšμ€ 각 λŒ€μΆœμ— λŒ€ν•΄ μ΄μŠ€μΌ€μ΄ν”„λœ 버전과 μ΄μŠ€μΌ€μ΄ν”„λ˜μ§€ μ•Šμ€ λ²„μ „μ˜ 두 가지 λΉ„νŠΈκ°€ μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ²˜μŒμ—λŠ” μ΄μŠ€μΌ€μ΄ν”„λ˜μ§€ μ•Šμ€ 버전을 μΆ”κ°€ν•©λ‹ˆλ‹€. μ°Έμ‘°κ°€ μ΄μŠ€μΌ€μ΄ν”„λ˜λ©΄ μ΄μŠ€μΌ€μ΄ν”„λœ λΉ„νŠΈλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€. λ³€μˆ˜(λ˜λŠ” μž„μ‹œ λ“±)κ°€ 죽으면 μ΄μŠ€μΌ€μ΄ν”„λ˜μ§€ μ•Šμ€ λΉ„νŠΈλ₯Ό μ’…λ£Œν•˜μ§€λ§Œ μ΄μŠ€μΌ€μ΄ν”„λœ λΉ„νŠΈ(μ„€μ •λœ 경우)λŠ” κ·ΈλŒ€λ‘œ λ‘‘λ‹ˆλ‹€. λ‚˜λŠ” 이것이 λͺ¨λ“  μ£Όμš” 예λ₯Ό ν¬ν•¨ν•œλ‹€κ³  λ―ΏμŠ΅λ‹ˆλ‹€.

cc @flaper87

이 λ¬Έμ œκ°€ 이에 ν•΄λ‹Ήν•©λ‹ˆκΉŒ?

use std::io::{MemReader, EndOfFile, IoResult};

fn read_block<'a>(r: &mut Reader, buf: &'a mut [u8]) -> IoResult<&'a [u8]> {
    match r.read(buf) {
        Ok(len) => Ok(buf.slice_to(len)),
        Err(err) => {
            if err.kind == EndOfFile {
                Ok(buf.slice_to(0))
            } else {
                Err(err)
            }
        }
    }
}

fn main() {
    let mut buf = [0u8, ..2];
    let mut reader = MemReader::new(~[67u8, ..10]);
    let mut block = read_block(&mut reader, buf);
    loop {
        //process block
        block = read_block(&mut reader, buf); //error here
}

λ‚˜λ₯Ό μ°Έμ‘°

#9113의 쒋은 예

λ‚˜λ₯Ό μ°Έμ‘°

λ‚΄κ°€ 틀릴 μˆ˜λ„ μžˆμ§€λ§Œ λ‹€μŒ μ½”λ“œλ„ 이 버그λ₯Ό μΉ˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

struct MyThing<'r> {
  int_ref: &'r int,
  val: int
}

impl<'r> MyThing<'r> {
  fn new(int_ref: &'r int, val: int) -> MyThing<'r> {
    MyThing {
      int_ref: int_ref,
      val: val
    }
  }

  fn set_val(&'r mut self, val: int) {
    self.val = val;
  }
}


fn main() {
  let to_ref = 10;
  let mut thing = MyThing::new(&to_ref, 30);
  thing.set_val(50);

  println!("{}", thing.val);
}

μ΄μƒμ μœΌλ‘œλŠ” set_val 호좜둜 μΈν•œ λ³€κ²½ κ°€λŠ₯ν•œ 차용이 ν•¨μˆ˜κ°€ λ°˜ν™˜λ˜λŠ” μ¦‰μ‹œ μ’…λ£Œλ©λ‹ˆλ‹€. ꡬ쑰체(및 κ΄€λ ¨ μ½”λ“œ)μ—μ„œ 'int_ref' ν•„λ“œλ₯Ό μ œκ±°ν•˜λ©΄ λ¬Έμ œκ°€ μ‚¬λΌμ§‘λ‹ˆλ‹€. 행동이 일관성이 μ—†μŠ΅λ‹ˆλ‹€.

@SergioBenitez λ‚˜λŠ” 그것이 같은 문제라고 μƒκ°ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. &mut self 참쑰의 수λͺ…이 ꡬ쑰체의 수λͺ…κ³Ό λ™μΌν•˜λ„λ‘ λͺ…μ‹œμ μœΌλ‘œ μš”μ²­ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ΄λ ‡κ²Œ ν•  ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€. set_val() 에 평생 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

fn set_val(&mut self, val: int) {
    self.val = val;
}

μˆ˜μ •ν•˜κΈ° 맀우 κΉŒλ‹€λ‘œμš΄ 또 λ‹€λ₯Έ 사둀λ₯Ό μ°Ύμ•˜μŠ΅λ‹ˆλ‹€.

/// A buffer which breaks chunks only after the specified boundary
/// sequence, or at the end of a file, but nowhere else.
pub struct ChunkBuffer<'a, T: Buffer+'a> {
    input:  &'a mut T,
    boundary: Vec<u8>,
    buffer: Vec<u8>
}

impl<'a, T: Buffer+'a> ChunkBuffer<'a,T> {
    // Called internally to make `buffer` valid.  This is where all our
    // evil magic lives.
    fn top_up<'b>(&'b mut self) -> IoResult<&'b [u8]> {
        // ...
    }
}

impl<'a,T: Buffer+'a> Buffer for ChunkBuffer<'a,T> {
    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        if self.buffer.as_slice().contains_slice(self.boundary.as_slice()) {
            // Exit 1: Valid data in our local buffer.
            Ok(self.buffer.as_slice())
        } else if self.buffer.len() > 0 {
            // Exit 2: Add some more data to our local buffer so that it's
            // valid (see invariants for top_up).
            self.top_up()
        } else {
            {
                // Exit 3: Exit on error.
                let read = try!(self.input.fill_buf());
                if read.contains_slice(self.boundary.as_slice()) {
                    // Exit 4: Valid input from self.input. Yay!
                    return Ok(read)
                }
            }
            // Exit 5: Accumulate sufficient data in our local buffer (see
            // invariants for top_up).
            self.top_up()
        }
    }

… 제곡:

/path/to/mylib/src/buffer.rs:168:13: 168:17 error: cannot borrow `*self` as mutable more than once at a time
/path/to/mylib/src/buffer.rs:168             self.top_up()
                                                        ^~~~
/path/to/mylib/src/buffer.rs:160:33: 160:43 note: previous borrow of `*self.input` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*self.input` until the borrow ends
/path/to/mylib/src/buffer.rs:160                 let read = try!(self.input.fill_buf());
                                                                            ^~~~~~~~~~
<std macros>:1:1: 3:2 note: in expansion of try!
/path/to/mylib/src/buffer.rs:160:28: 160:56 note: expansion site
/path/to/mylib/src/buffer.rs:170:6: 170:6 note: previous borrow ends here
/path/to/mylib/src/buffer.rs:149     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
...
/path/to/mylib/src/buffer.rs:170     }

이것은 기본적으둜 #12147κ³Ό λ™μΌν•©λ‹ˆλ‹€. read λ³€μˆ˜λŠ” λ‚΄λΆ€ λ²”μœ„μ— λ¬»ν˜€ μžˆμ§€λ§Œ return read 의 수λͺ…을 전체 ν•¨μˆ˜μ˜ 수λͺ…에 λ°”μΈλ”©ν•©λ‹ˆλ‹€. λŒ€λΆ€λΆ„μ˜ λͺ…λ°±ν•œ ν•΄κ²° 방법은 μ‹€νŒ¨ν•©λ‹ˆλ‹€.

  1. Buffer μΈν„°νŽ˜μ΄μŠ€λŠ” λ‚΄κ°€ 두 번째둜 μœ νš¨μ„±μ„ κ²€μ‚¬ν•œ 데이터λ₯Ό λ°˜ν™˜ν•œλ‹€κ³  보μž₯ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— input.fill_buf 두 번 ν˜ΈμΆœν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ‚΄κ°€ 이것을 _do_ ν•˜λ©΄ μ½”λ“œκ°€ 기술적으둜 μ˜¬λ°”λ₯΄μ§€ μ•Šμ§€λ§Œ μœ ν˜• κ²€μ‚¬κΈ°λŠ” 이λ₯Ό 만쑱슀럽게 μ „λ‹¬ν•©λ‹ˆλ‹€.
  2. top_up 에 λŒ€ν•΄ λ§Žμ€ 것을 ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ³΅μž‘ν•œ λ°©μ‹μœΌλ‘œ λͺ¨λ“  것을 λ³€κ²½ν•΄μ•Ό ν•˜λŠ” μ‚¬μ•…ν•œ μ½”λ“œμ΄κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
  3. λ¬Έμ œκ°€ λ˜λŠ” bind+test+return을 λ‹€λ₯Έ ν•¨μˆ˜λ‘œ 이동할 수 μ—†μŠ΅λ‹ˆλ‹€. μƒˆ APIμ—λŠ” μ—¬μ „νžˆ λ™μΌν•œ λ¬Έμ œκ°€ 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€( if let _then_ bind?λ₯Ό ν…ŒμŠ€νŠΈν•  수 μžˆλŠ” 경우 μ œμ™Έ).

'a μ œμ•½ 쑰건이 μ΄μƒμ μœΌλ‘œ read λ‹€μ‹œ μ „νŒŒλ˜μ–΄μ„œλŠ” μ•ˆ λ˜λŠ” κ²ƒμ²˜λŸΌ λŠκ»΄μ§‘λ‹ˆλ‹€. ν•˜μ§€λ§Œ λ‚œ μ—¬κΈ° λ‚΄ 머리 μœ„μ— μžˆμ–΄μš”. λ‹€μŒμ—λŠ” if let λ₯Ό μ‹œλ„ν•˜κ² μŠ΅λ‹ˆλ‹€.

κΈ€μŽ„μš”, if let λŠ” μ–΄μ ―λ°€ λΉŒλ“œμ— ν¬ν•¨λ˜μ§€ μ•Šμ•˜μ§€λ§Œ, μ•„λ§ˆλ„ AST μž¬μž‘μ„±μΌ λΏμ΄λ―€λ‘œ match 와 같은 λ°©μ‹μœΌλ‘œ μ‹€νŒ¨ν•  것 κ°™μŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ—μ„œλ„ μ‹œλ„).

unsafe μ‚¬μš©ν•˜μ§€ μ•Šκ³  μ§„ν–‰ν•˜λŠ” 방법을 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€.

λ‚΄ ν˜„μž¬ 해킹은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

impl<'a,T: Buffer+'a> Buffer for ChunkBuffer<'a,T> {
    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        // ...

            { // Block A.
                let read_or_err = self.input.fill_buf();
                match read_or_err {
                    Err(err) => { return Err(err); }
                    Ok(read) => {
                        if read.contains_slice(self.boundary.as_slice()) {
                               return Ok(unsafe { transmute(read) });
                        }
                    }
                }
            }
            self.top_up()

μ—¬κΈ°μ„œ 이둠은 read ( self.input 에 바인딩됨)의 수λͺ…을 μ‚­μ œν•˜κ³  self.input λ₯Ό μ†Œμœ ν•˜λŠ” self 기반으둜 μƒˆ 수λͺ…을 μ¦‰μ‹œ μ μš©ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. self.input . μ΄μƒμ μœΌλ‘œλŠ” read κ°€ 블둝 A 와 같은 μ–΄νœ˜ 수λͺ…을 κ°–κΈ°λ₯Ό μ›ν•˜κ³  return μ „λ‹¬ν–ˆκΈ° λ•Œλ¬Έμ— _lexical_ 블둝 μˆ˜μ€€κΉŒμ§€ λŒμ–΄μ˜¬λ¦¬λŠ” 것을 μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λΆ„λͺ…νžˆ 수λͺ… κ²€μ‚¬κΈ°λŠ” μ—¬μ „νžˆ κ²°κ³Όκ°€ 'a 와 ν˜Έν™˜λ˜λŠ” 수λͺ…을 가지고 μžˆμŒμ„ 증λͺ…ν•΄μ•Ό ν•˜μ§€λ§Œ 이것이 LIFETIME( read )이 LIFETIME( 'a κ³Ό ν†΅ν•©λ˜μ–΄μ•Ό 함을 μ˜λ―Έν•˜λŠ” 이유λ₯Ό μ΄ν•΄ν•˜μ§€ λͺ»ν•©λ‹ˆλ‹€

λ‚΄κ°€ μ—„μ²­λ‚˜κ²Œ ν˜Όλž€μŠ€λŸ½κ±°λ‚˜ λ‚΄ μ½”λ“œκ°€ λ”μ°ν•˜κ²Œ μ•ˆμ „ν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. :-) ν•˜μ§€λ§Œ 아무 문제 없이 return self.input.fill_buf() λ₯Ό ν˜ΈμΆœν•  수만 μžˆλ‹€λ©΄ 이것이 μž‘λ™ν•΄μ•Ό ν•  것 κ°™μŠ΅λ‹ˆλ‹€. κ·Έ 직관을 κ³΅μ‹ν™”ν•˜λŠ” 방법이 μžˆμŠ΅λ‹ˆκΉŒ?

@emk λ”°λΌμ„œ 이것은 SEME μ˜μ—­(즉, μ–΄νœ˜κ°€ μ•„λ‹Œ μ˜μ—­)이 적어도 자체적으둜 μˆ˜μ •λ˜μ§€ μ•ŠλŠ” "ν•˜λ“œ μ½”λ“œ"μž…λ‹ˆλ‹€. μ»΄νŒŒμΌλŸ¬μ—μ„œ 잘 μˆ˜μ •ν•˜λŠ” 방법에 λŒ€ν•œ λͺ‡ 가지 아이디어가 μžˆμ§€λ§Œ SEME μ˜μ—­μ— λŒ€ν•œ μ‚¬μ†Œν•œ ν™•μž₯μž…λ‹ˆλ‹€. 일반적으둜 μ½”λ“œλ₯Ό μž¬κ΅¬μ„±ν•˜μ—¬ 이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 방법이 μžˆμŠ΅λ‹ˆλ‹€. λ‚΄κ°€ 그것을 가지고 놀고 쒋은 예λ₯Ό λ§Œλ“€ 수 μžˆλŠ”μ§€ 보자.

이것이 1.0에 λŒ€ν•΄ μž¬κ²€ν† λ˜κ³  μžˆλŠ”μ§€ μ•Œκ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 이것은 μ΅œκ·Όμ— _λ§Žμ€_ 올라였고 있으며, 1.0이 관심을 λͺ¨μœΌκ²Œ 되면 이것이 νŽ˜μ΄νΌμ»·μ—μ„œ μƒμ²˜λ‘œ μ‚¬λΌμ§ˆκΉŒ λ‘λ ΅μŠ΅λ‹ˆλ‹€. Rust의 κ°€μž₯ λˆˆμ— 띄고 ν™”μ œκ°€ 된 κΈ°λŠ₯인 μ°¨μš©μ€ μ„Έλ ¨λ˜κ³  μ‚¬μš© κ°€λŠ₯ν•˜λ„λ‘ ν•˜λŠ” 것이 맀우 μ€‘μš”ν•©λ‹ˆλ‹€.

RFC에 이에 λŒ€ν•œ 기간이 μžˆμŠ΅λ‹ˆκΉŒ?

@nikomatsakis λ„μ›€μ΄λœλ‹€λ©΄ Entry APIμ—μ„œ μž‘λ™ν•˜μ§€ μ•ŠλŠ” μ‹€μ œ κ°„λ‹¨ν•œ μ˜ˆκ°€ μžˆμŠ΅λ‹ˆλ‹€.

use std::collections::SmallIntMap;

enum Foo<'a>{ A(&'a mut SmallIntMap<uint>), B(&'a mut uint) }

fn main() {
    let mut map = SmallIntMap::<uint>::new();
    do_stuff(&mut map);
}

fn do_stuff(map: &mut SmallIntMap<uint>) -> Foo {
    match map.find_mut(&1) {
        None => {},  // Definitely can't return A here because of lexical scopes
        Some(val) => return B(val),
    }
    return A(map); // ERROR: borrowed at find_mut???
}

놀이터

@bstrie @pcwalton κ³Ό @zwarich λŠ” 이 μž‘μ—…μ„ μ‹€μ œλ‘œ κ΅¬ν˜„ν•˜λŠ” 데 μ‹œκ°„μ„ λ³΄λƒˆμŠ΅λ‹ˆλ‹€(RFCκ°€ ν•¨κ»˜ 제곡될 수 있음). 그듀은 μ˜ˆμƒλ³΄λ‹€ 훨씬 더 λ§Žμ€ μž‘μ—…μ΄ ν•„μš”ν•˜λ‹€λŠ” 것을 μ˜λ―Έν•˜λŠ” μ˜ˆμƒμΉ˜ λͺ»ν•œ λ³΅μž‘μ„±μ— μ§λ©΄ν–ˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ μ œν•œμ΄ μ€‘μš”ν•˜κ³  μ–Έμ–΄μ˜ 첫인상에 영ν–₯을 쀄 수 μžˆλ‹€λŠ” 점에 λͺ¨λ‘ λ™μ˜ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 이미 μ˜ˆμ •λœ 이전 버전과 ν˜Έν™˜λ˜μ§€ μ•ŠλŠ” λ³€κ²½ 사항과 κ· ν˜•μ„ λ§žμΆ”κΈ°κ°€ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

1.0μ—μ„œ 이것이 ν•΄κ²°λ˜μ§€ μ•ŠμœΌλ©΄ 이 λ¬Έμ œκ°€ 차용 검사 AFAIKμ—μ„œ 본질적으둜 ν•΄κ²°ν•  수 μ—†λŠ” λ¬Έμ œκ°€ 아닐 λ•Œ μ‚¬λžŒλ“€μ΄ 차용 검사 μ ‘κ·Ό 방식을 μ „μ μœΌλ‘œ λΉ„λ‚œν•˜κ²Œ 될 μ’…λ₯˜μ˜ 것이라고 μƒκ°ν•©λ‹ˆλ‹€.

@blaenk 빌린 체컀λ₯Ό λΉ„λ‚œν•˜μ§€ μ•ŠλŠ” 것은 μ–΄λ ΅μŠ΅λ‹ˆλ‹€. μ €λŠ” 맀일 이것과 μœ μ‚¬ν•œ(@Gankro와 같은) 문제λ₯Ό κ²ͺμ—ˆμŠ΅λ‹ˆλ‹€. 일반적인 μ†”λ£¨μ…˜μ΄ νšŒμ „(예: ν•΄κ²° 방법)/λ˜λŠ” μ½”λ“œλ₯Ό 보닀 "λΆˆλ³€"ν•˜κ³  κΈ°λŠ₯적으둜 μž¬κ΅¬μ„±ν•˜κΈ° μœ„ν•œ 주석일 λ•Œ μ‹€λ§μŠ€λŸ½μŠ΅λ‹ˆλ‹€.

@mtanski λ„€, ν•˜μ§€λ§Œ 잘λͺ»μ€ 차용 검사기 AFAIK에 _does_ μžˆμŠ΅λ‹ˆλ‹€. 그것을 λΉ„λ‚œν•˜λŠ” 것은 μ˜³μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‚΄κ°€ λ§ν•˜λŠ” 것은 μ‹ κ·œ μ΄λ―Όμžλ“€μ΄ 그것이 μ°¨μž… 확인 _접근법_κ³Ό κ΄€λ ¨λœ 본질적이고 근본적이며 ν•΄κ²°ν•  수 μ—†λŠ” 문제라고 믿게 ν•  수 있고 AFAIKλŠ” 잘λͺ»λœ 믿음이라고 믿게 ν•  수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

경우: "let p = &...; use-pa-bit-but-never-again; μ˜ˆμƒ λŒ€μΆœ 만기일;" ν˜„μž¬λ‘œμ„œλŠ” ν•΄λ‹Ή μ°¨μš©μ— λŒ€ν•œ λ²”μœ„ 끝을 μˆ˜λ™μœΌλ‘œ μ„ μ–Έν•˜λŠ” kill(p) λͺ…령이 ν—ˆμš©λ©λ‹ˆλ‹€. 이후 λ²„μ „μ—μ„œλŠ” 이 λͺ…λ Ήμ–΄κ°€ ν•„μš”ν•˜μ§€ μ•Šμ€ 경우 이 λͺ…λ Ήμ–΄λ₯Ό λ¬΄μ‹œν•˜κ±°λ‚˜ 이후에 p의 μž¬μ‚¬μš©μ΄ κ°μ§€λ˜λ©΄ 였λ₯˜λ‘œ ν”Œλž˜κ·Έλ₯Ό 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.

/* (wanted) */
/*
fn main() {

    let mut x = 10;

    let y = &mut x;

    println!("x={}, y={}", x, *y);

    *y = 11;

    println!("x={}, y={}", x, *y);
}
*/

/* had to */
fn main() {

    let mut x = 10;
    {
        let y = &x;

        println!("x={}, y={}", x, *y);
    }

    {
        let y = &mut x;

        *y = 11;
    }

    let y = &x;

    println!("x={}, y={}", x, *y);
}

이λ₯Ό μˆ˜ν–‰ν•˜λŠ” μ„œκ³‘μ— drop() λ©”μ„œλ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ•„λ‹Œ 것 κ°™λ‹€
λ³€κ²½ κ°€λŠ₯ν•œ μ°¨μš©μ„ 돕기 μœ„ν•΄.

2015λ…„ 4μ›” 5일 μΌμš”μΌ μ˜€ν›„ 1μ‹œ 41λΆ„ axeoth [email protected]이 λ‹€μŒκ³Ό 같이 μΌμŠ΅λ‹ˆλ‹€.

/* (원함) _//_fn main() { let mut x = 10; ν•˜μž y = &mut x; println!("x={}, y={}", x, _y); *y = 11; println!("x={}, y={}", x, *y);}_/
/* ν•΄μ•Ό */fn main() {

let mut x = 10;
{
    let y = &x;

    println!("x={}, y={}", x, *y);
}

{
    let y = &mut x;

    *y = 11;
}

let y = &x;

println!("x={}, y={}", x, *y);

}

β€”
이 이메일에 직접 λ‹΅μž₯ν•˜κ±°λ‚˜ GitHubμ—μ„œ ν™•μΈν•˜μ„Έμš”.
https://github.com/rust-lang/rust/issues/6393#issuecomment -89848449.

https://github.com/rust-lang/rfcs/issues/811 에 μ°¬μ„±ν•˜μ—¬ μ’…λ£Œ

@metajack 원본 μ½”λ“œμ— λŒ€ν•œ λ§ν¬λŠ” 404μž…λ‹ˆλ‹€. 이 버그λ₯Ό μ½λŠ” μ‚¬λžŒλ“€μ„ μœ„ν•΄ 인라인으둜 포함할 수 μžˆμŠ΅λ‹ˆκΉŒ?

μ•½κ°„μ˜ 파기 후에 이것이 원본 μ½”λ“œμ™€ λ™μΌν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.
https://github.com/servo/servo/blob/5e406fab7ee60d9d8077d52d296f52500d72a2f6/src/servo/layout/box_builder.rs#L374

λ˜λŠ” 이 버그λ₯Ό μ‹ κ³ ν•  λ•Œ μ‚¬μš©ν•œ ν•΄κ²° λ°©λ²•μž…λ‹ˆλ‹€. λ³€κ²½ μ „μ˜ μ›λž˜ μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
https://github.com/servo/servo/blob/7267f806a7817e48b0ac0c9c4aa23a8a0d288b03/src/servo/layout/box_builder.rs#L387 -L399

μ΄λŸ¬ν•œ νŠΉμ • μ˜ˆκ°€ λ…ΉμŠ¨ 1.0 이전 λ²„μ „μ΄μ—ˆκΈ° λ•Œλ¬Έμ— ν˜„μž¬ μ–Όλ§ˆλ‚˜ 관련성이 μžˆλŠ”μ§€ 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€.

@metajack 이 문제의 맨 μœ„μ— 맀우 κ°„λ‹¨ν•œ(1.0 이후) μ˜ˆμ œκ°€ 있으면 쒋을 κ²ƒμž…λ‹ˆλ‹€. 이 λ¬Έμ œλŠ” 이제 https://github.com/rust-lang/rfcs/issues/811의 μΌλΆ€μž…λ‹ˆλ‹€.

fn main() {
    let mut nums=vec![10i,11,12,13];
    *nums.get_mut(nums.len()-2)=2;
}

λ‚˜λŠ” λ‚΄κ°€ λΆˆν‰ν–ˆλ˜ 것이 λ‹€μŒκ³Ό κ°™λ‹€κ³  μƒκ°ν•œλ‹€.
https://is.gd/yfxUfw

κ·Έ νŠΉλ³„ν•œ κ²½μš°λŠ” 이제 μž‘λ™ν•˜λŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€.

@vitiral λ‚΄κ°€ μ μš©ν•œλ‹€κ³  μƒκ°ν•˜λŠ” μ˜€λŠ˜λ‚ μ˜ Rust의 예:

fn main() {
    let mut vec = vec!();

    match vec.first() {
        None => vec.push(5),
        Some(v) => unreachable!(),
    }
}

None 암이 μ°¨μš©μ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.

ν₯λ―Έλ‘­κ²Œλ„ Some μ•”μ—μ„œ int λ₯Ό μΊ‘μ²˜ν•˜μ§€ μ•ŠμœΌλ©΄(예: Some(_) ) μ»΄νŒŒμΌλ©λ‹ˆλ‹€.

@wyverland 였 μ•Ό, μ–΄μ œ μ³€λŠ”λ° κ½€

@metajack ν•΄λ‹Ή 예제λ₯Ό ν¬ν•¨ν•˜λ„λ‘ 첫 번째 κ²Œμ‹œλ¬Όμ„ νŽΈμ§‘ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

아직 야간에 μ μ€‘λ˜μ§€λŠ” μ•Šμ•˜μ§€λ§Œ 이것이 이제 μ»΄νŒŒμΌλœλ‹€κ³  λ§ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

#![feature(nll)]

fn main() {
    let mut vec = vec!();

    match vec.first() {
        None => vec.push(5),
        Some(v) => unreachable!(),
    }
}
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰