μ μ΄λ° μΌμ΄ λ°μνλμ§ λͺ¨λ₯΄κ² μ§λ§ IRCμ rovarμ XMPPwockyλ μ΄κ²μ΄ μ»΄νμΌλ¬ λ²κ·ΈλΌκ³ λ―Ώμμ΅λλ€.
struct A {
a: i32
}
impl A {
fn one(&mut self) -> &i32{
self.a = 10;
&self.a
}
fn two(&mut self) -> &i32 {
loop {
let k = self.one();
if *k > 10i32 {
return k;
}
}
}
}
... λ€μ μ€λ₯κ° λ°μν©λλ€ ...
<anon>:12:21: 12:25 error: cannot borrow `*self` as mutable more than once at a time
<anon>:12 let k = self.one();
^~~~
<anon>:12:21: 12:25 note: previous borrow of `*self` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*self` until the borrow ends
<anon>:12 let k = self.one();
^~~~
<anon>:17:6: 17:6 note: previous borrow ends here
<anon>:10 fn two(&mut self) -> &i32 {
...
<anon>:17 }
^
error: aborting due to previous error
playpen: application terminated with error code 101
ν₯λ―Έλ‘κ²λ λ λ²μ§Έ λ°©λ²μ΄ λ€μκ³Ό κ°μ΄ λ³κ²½λλ©΄ ...
fn two(&mut self) -> &i32 {
loop {
let k = self.one();
return k;
}
}
μ΄κ²μ μ μ»΄νμΌλ©λλ€.
λμ΄ ν : http://is.gd/mTkfw5
λλ μ΄κ²μ΄ μ¬λ°λ₯Έ νλμ΄λΌκ³ λ―Ώμ΅λλ€. μ΄μ λ₯Ό νμΈνλ €λ©΄ λͺ μ μ μλͺ μ£Όμμ΄μλ μ½λλ₯Ό κ³ λ €νμΈμ.
struct A {
a: i32
}
impl A {
fn one<'a>(&'a mut self) -> &'a i32{
self.a = 10;
&self.a
}
fn two<'a>(&'a mut self) -> &'a i32 {
loop {
let k = self.one();
if *k > 10i32 {
return k;
}
}
}
}
two
λ μ£Όμ΄μ§ κ°λ³ μ°¨μ©κ³Ό λμΌν μλͺ
μ κ°μ§ μ°Έμ‘°λ₯Ό λ°νν΄μΌν©λλ€. κ·Έλ¬λ κ·Έκ² λλ¬Έμ. μ΄λ k
νμ 'a
κ° μμ΄μΌ ν¨μ μλ―Έν©λλ€. κ·Έλ¬λ, λ°ν λ κ° one
μλͺ
κ°λλ‘ 'a
μ μ
λ ₯ one
λν μλͺ
μ κ°μ§κ³ μμ΄μΌ 'a
. μ΄ μλ¨μ λ
Ήνμ§ μλλ‘ κ°μ νλ κ²μ΄ "reborrow" self
κ³Όμ μ΄λ one
. κ°λ³ μ°Έμ‘°λ μ νμ΄λ―λ‘ ν λ²λ§ μ΄λν μ μμ§λ§ loop
λ one
λμΌν κ°λ³ μ°Έμ‘°λ‘ λ°λ³΅μ μΌλ‘ νΈμΆν΄μΌ ν μ μμμ μλ―Έν©λλ€.
λ λ²μ§Έ μμ λ Rustκ° λ£¨νκ° ν λ²λ§ μ€νλλ€λ κ²μ μ μ μκΈ° λλ¬Έμ μλνλ―λ‘ self
λ ν λ²λ§ μ΄λλ©λλ€.
μ΄κ²μ λΉ μ΄νμ μΈ μ°¨μ λ¬Έμ μ²λΌ 보μ λλ€. 루ν μμ΄λ λΉμ·ν λμμ μ»μ μ μμ΅λλ€.
struct Foo { data: Option<i32> }
fn main() {
let mut x = Foo{data: Some(1)};
foo(&mut x);
}
fn foo(x: &mut Foo) -> Option<&mut i32> {
if let Some(y) = x.data.as_mut() {
return Some(y);
}
println!("{:?}", x.data);
None
}
<anon>:14:22: 14:28 error: cannot borrow `x.data` as immutable because it is also borrowed as mutable
<anon>:14 println!("{:?}", x.data);
^~~~~~
note: in expansion of format_args!
<std macros>:2:43: 2:76 note: expansion site
<std macros>:1:1: 2:78 note: in expansion of println!
<anon>:14:5: 14:30 note: expansion site
<anon>:10:22: 10:28 note: previous borrow of `x.data` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x.data` until the borrow ends
<anon>:10 if let Some(y) = x.data.as_mut() {
^~~~~~
<anon>:16:2: 16:2 note: previous borrow ends here
<anon>:9 fn foo(x: &mut Foo) -> Option<&mut i32> {
...
<anon>:16 }
^
error: aborting due to previous error
Rustcλ μ‘°κ±΄λΆ μ°¨μ μμ΅μ "κ±°λ"ν μ μμ΅λλ€.
CC @pcwalton
λ¬Έμ λ μ€μ λ‘ λ°ν κ°μ κ°λ³μ±μ΄ μ¬μ©λμ§ μκ³ ν¨μ μΈμμ κ°λ³μ±μ΄ μ¬μ©λλ€λ κ²μ λλ€.
λ€μ μ½λλ λ³κ²½ λΆκ°λ₯ν μ°Έμ‘°λ₯Ό λ°ννλ λ³κ²½ ν¨μλ₯Ό νΈμΆν©λλ€. κ·Έ νμλ λΆλ³ μ°Έμ‘°λ₯Ό μ·¨ν μ μμ΅λλ€.
struct Foo (u8);
impl Foo {
fn bar(&mut self) -> &u8 {
self.0 += 1;
&self.0
}
}
fn main() {
let mut x = Foo(42);
let a = x.bar(); // note: borrow of `x` occurs here
let b = x.0; // error: cannot use `x.0` because it was mutably borrowed
}
λλ μ΅μ μΌκ°μ μ¬μ νμ΄ λ¬Έμ λ₯Ό κ²ͺκ³ μμ΅λλ€. λ°νμ΄μλ ν¨μκ° μ°¨μ© κ²μ¬κΈ°λ₯Ό ν΅κ³ΌνλλΌλ ν¨μκ° λλ λκΉμ§ λ°νμ μλͺ μ΄μλ κ²μΌλ‘ κ°μ£Όνλ κ²μΌλ‘ 보μ λλ€. λ°ν μ§μ μ΄ ν¨μλ₯Ό μ‘°κΈ°μ μ’ λ£νλ λ°©λ²μ κ³ λ €νλ©΄ λ€μ μ΄μν΄ λ³΄μ λλ€.
@Gankro μ μμ λ₯Ό
μ΄κ²μ λΉ μ΄ν μλͺ μμ μ°¨λ¨λλ©° MIRμμ μ°¨λ¨λ©λλ€. μ΄μμ μΌλ‘λ 2016 λ λ§κΉμ§ μμ λ κ²μ΄μ§λ§ 곧 μμ λμ§λ μμ κ²μ λλ€.
λ΄λΆμ λν ν λ‘ : https://internals.rust-lang.org/t/relaxing-the-borrow-checker-for-fn-mut-self-t/3256
λΉ μ΄ν μ°¨μ© κΈ°λ₯ ν λ‘ : https://github.com/rust-lang/rfcs/issues/811
κ·Έλμ [internals thread]λ₯Ό μ½μΌλ©΄ μ΄κ²μ΄ κ³ μΉ μμλ κ²μ²λΌ λκ»΄μ§λλ€ (NLLμ μ¬μ©ν΄λ). λκ΅°κ° νμΈν μ μμ΅λκΉ? (@eddyb?)
cc @ ν΄μ-μ₯ / μ₯
μ΄κ²μ μ€μ λ‘ NLLμ΄κ³ , λ΄κ° μ°©κ°νμ§ μμΌλ©΄ λ΄κ° λ§λ λ€μν μ μμΌλ‘ μμ λ κ²μ
λλ€. μ΄κ²μ λλ΅ λ΄ μ²« λΈλ‘κ·Έ κ²μλ¬Όμ "λ¬Έμ μ¬λ‘ # 3"μ ν΄λΉν©λλ€. μ΄κ²μ΄ μλνλ μ΄μ μ λν κΈ°λ³Έ μμ΄λμ΄ ( μ΅μ λΈλ‘κ·Έ κ²μλ¬Όμ 곡μ μΈ‘λ©΄ if
λΆκΈ°μ 'a
λκΉμ§ λ§ μ°μ₯νλ©΄λλ€λ κ²μ
λλ€. if
λ₯Ό μ λ°νλ return
.
@nikomatsakis NLLμ΄μ΄ λ¬Έμ μ μ΄λ»κ² μνΈ μμ©νλμ§ μμΈν &mut
μ°Έμ‘°μ λ΄ μ μ λͺ¨λΈμμλ move λλ reborrowλ₯Ό ν΅ν΄ μ λ¬ν μ μ΄λ λͺ¨λκ° νμνκ³ self
μ μ¬μ¬μ©μ΄ νμνλ€λ κ²μ
λλ€. λμ€μ λ€μ λΉλ €μΌ ν©λλ€. λ΄ μ΄ν΄μ λ°λ₯΄λ©΄ μλ‘ μ¬ λΉλ¦° &mut
μ°Έμ‘°μ μλͺ
μ &mut
-referenceλ₯Ό 보μ ν λ³μμ μλͺ
μ μν΄ μ νλ©λλ€.μ΄ κ²½μ°μλ self
λ³μμ μν΄ μ νλ©λλ€. λ°λΌμ ν¨μ νΈμΆ μΈλΆλ‘ νμ₯ ν μ μμ΅λλ€. NLLμ΄ μ¬ μ°¨μ
μ νμ λ³κ²½ν©λκΉ (λλ κ·Έλ¬ν μ νμ΄ μμ μλ μμ)?
λνμ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ κ²μ΄ λ³Έμ§μ μΌλ‘ NLLκ³Ό κ΄λ ¨μ΄ μλμ§ μλλ©΄ μ§κ΅ ν μ μλμ§ κΆκΈν©λλ€. νμλΌλ©΄ NLL μ΄μ μ μμ μ ν κ°μΉκ° μμ΅λκΉ?
λν NLLμ΄μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ €λ κ²½μ° NLLμμ μ΄λκ³Ό μ¬ μ°¨μ μ€μμ μλμΌλ‘ μ νν νμκ° μλ€λ μλ―Έμ λκΉ?
μ‘°λ§κ° μμ λ μμ μ λκΉ?
λΏ‘λΏ‘
NLLμ΄μ΄ λ¬Έμ μ μ΄λ»κ² μνΈ μμ©νλμ§ μμΈν μ€λͺ ν΄ μ£Όμκ² μ΅λκΉ?
μμ½μ κ°μ΄ μ΄λ€ κ²½λ‘μ κΈ°λ₯ λ°μΌλ‘ λ°νλ©λλ€ κ²½μ° μ€λ, λμΆμ λͺ¨λ κ²½λ‘μ κΈ°λ₯μ λλ¨Έμ§ λΆλΆμ λν μ ν¨ν κ²μ΄μ΄μΌνλ€λ κ²μ λλ€. λ΄κ° μμ±ν NLL μ μμ λ°λΌ κ·Έ μ νμ΄ ν΄μ λμμ΅λλ€.
λ μμΈνκ² μ¬κΈ°μμ μ κ΅ν μλͺ
μ λ°μΌλ©΄ μλͺ
μ΄ 'a
μ°Έμ‘°λ₯Ό λ°νν΄μΌ ν¨μ μ μ μμ΅λλ€.
fn two<'a>(&'a mut self) -> &'a i32 { .. }
μ΄μ let k = self.one()
νΈμΆ ν λ€μ k
λ₯Ό λ°ννλ κ²μ νμΈν©λλ€. μ ν κ²μμ΄ μλ¨ k
μμ΄μΌν©λλ€ &'a i32
. μ΄λ λ€μ self.one()
νΈμΆ ν λ &'a mut Self
μ νμΌλ‘ self
μ°¨μ©μ μ 곡ν΄μΌ ν¨μ μλ―Έν©λλ€. λ°λΌμ let k = self.one()
self
μμ νμ 'a
λ‘ self
λμΆμ λ°νν©λλ€. μ΄ μλͺ
μ 루ν (μ€μ λ‘ μ 체 ν¨μ)λ³΄λ€ ν¬κΈ° λλ¬Έμ 루νλ₯Ό λμ λ€λ λ μ§μλμ΄ μ€λ₯λ³΄κ³ κ° λ°μν©λλ€. λ΄κ° μ μνλ NLL κ·μΉμμμ μλͺ
k
λ¨μ§κΉμ§ μ°μ₯ ν νμκ° 'a
κ²½μ° if
μ·¨ν΄μ§ λ€. λ°λΌμ if
λ₯Όλ°μ§ μμΌλ©΄ λμΆμ΄ λ μΌμ° μ’
λ£ λ μ μμ΅λλ€.
λμμ΄ λλμ?
@ osa1
μ‘°λ§κ° μμ λ μμ μ λκΉ?
μ΄ μμ μ μννκΈ° μ μ μμ§ λͺ λ¨κ³λ₯Ό κ±°μ³μΌνμ§λ§ νμν 리ν©ν λ§μ μννκΈ°μν μ κ·Ήμ μΈ μμ μ΄ μμ΅λλ€.
λΏ‘ λΉ΅λ¨
κ°μ¬ν©λλ€. λ€μ λμμ΄λμμ΅λλ€. νμ§λ§ μ κ° μ΄ν΄νμ§ λͺ»νλ ν κ°μ§ μμ κ²μ΄ μμ΅λλ€. self
λ₯Ό μ½λμ μμ±ν λ μ νν μ΄λ€ μΌμ΄ λ°μνλμ§ β self
μ μ¬ μ°¨μ
μ΄ μλνλ λ°©μμ
λλ€. νΈμΆμ λ΄λΆμμ μ½λλ₯Ό μΈλΌμΈνλ "λ¬Έμ μ¬λ‘ 3"( get_default
)μ λν μ€λͺ
μ μ½μμ§λ§ self
μ λͺ¨λ μ¬μ©μ μ°¨μ©μΌλ‘ λ³κ²½νμ΅λλ€. map
λ³μλ₯Ό μ§μ μ¬μ©νμ¬ desugaringμΌλ‘ ν΄κ²°λμ§ μμμ΅λλ€.
μ κ° κ°νμλ λΆλΆμ λ€μκ³Ό κ°μ΅λλ€. let k = self.one()
νΈμΆνλ©΄ self
λ₯Ό μ΄λν μ μμΌλ―λ‘ (λμ€μ νμνκΈ° λλ¬Έμ) λΉλ¦° κ²μΌλ‘ κ°μ£Όλ©λλ€. λμ€μ 쑰건λΆλ‘ k
λ°ννλ―λ‘, μ°¨μ©μ ν¨μ νΈμΆλ³΄λ€ μ€λ μ§μλλ 'a
μλͺ
μ κ°μ ΈμΌν©λλ€. κ·Έλ¬λ! ν¨μκ° λλ λκΉμ§λ§ μ μ§λλ self
μμ μ°¨μ©νμ΅λλ€. κ·Έ μ νμ 'a
λ₯Ό μ€μ¬μ£Όλ κ²μ²λΌ 보μ΄λ―λ‘ NLL νμμλ μ μ λͺ¨λΈμμ "μΆ©λΆν μ€λ μ΄μ§ μμ"μ€λ₯κ° λ°μν΄μΌν©λλ€.
@krdln μ°λ¦¬λ μ€μ λ‘ *self
μμ μ°¨μ©νμ΅λλ€. μ¦, selfκ° μ°Έμ‘°νλ κ²μ λ€μ λΉ λ Έμ΅λλ€. μ°λ¦¬λ λμΆ ν μ μλλ‘ νμ© *self
νμμ΄ μ€λ μ΄μ§μ λν΄ self
μ μ ν λλ¬Έμ μμ μ self
μ 체 μλͺ
μ λν 'μ κΈ'μ μλ―Έ 'a
. λ°λΌμ 'a
λμ selfκ° λ μ΄μ μ¬μ©λμ§ μλλ€λ κ²μ 보μ₯ ν μμλ ν κ²°κ³Όλ λ°°νμ μ°Έμ‘°κ°λμ΄μΌν©λλ€.μ΄ κ²½μ° fnμ΄ λ°ν λ ν selfκ° νλμμΌλ―λ‘ μ¬μ©νμ§ μμΌλ―λ‘ fnμ΄ λλ λκΉμ§ selfκ° μ¬μ©λμ§ μλλ‘ λ³΄μ₯ν©λλ€. (μ μ΄λ κ·Έκ² μ¬μ€ μ΄κΈΈ λ°λλλ€. =)
μ΄κ²μ λΉ μ΄ν μλͺ μμ μ°¨λ¨λλ©° MIRμμ μ°¨λ¨λ©λλ€. μ΄μμ μΌλ‘λ 2016 λ λ§κΉμ§ μμ λ κ²μ΄μ§λ§ 곧 μμ λμ§λ μμ κ²μ λλ€.
κ·Έλ€μ§ λλμ§λ μμ§λ§ λΉ μ΄ν μλͺ κΈ°λ₯μ μΌλ©΄ μ΄κΈ° μμ κ° μ€μ λ‘ μΌκ°μ μ»΄νμΌ λλ€λ κ²μ νμΈνμ΅λλ€.
λΆλ³μ μ°¨μ μ΄ λ무 μ€λ μ¬λ κ²μ²λΌ 보μ΄λ νλ‘λμ μμ λΉμ·ν λ¬Έμ κ° λ°μνλ€κ³ μκ°ν©λλ€ ( ν΄κ²° λ°©λ² ).
λν starwedμ μ½λ κ° λ μ΄μ μ΅μ μΌκ°μ μ»΄νμΌλμ§ μλλ€λ μ λ μΈκΈν΄μΌν©λλ€. @oberien μ " regression-from-nightly-to-nightly
"νκ·Έλ₯Ό μ μνμΌλ©° μ΄κ²μ΄ κΈ΄κΈν λ¬Έμ μΈ κ²½μ° @nikomatsakis νκ·Έλ₯Ό λ°μμ΅λλ€ . :)
λ§€μ° μ μ¬ν μμ μ μλνλμ΄ λ¬Έμ λ₯Ό λ°κ²¬νμ΅λλ€ (νμ¬ nllμμλ νμ©λμ§ μμ).
fn f(vec: &mut Vec<u8>) -> &u8 {
if let Some(n) = vec.iter_mut().find(|n| **n == 1) {
*n = 10;
n
} else {
vec.push(10);
vec.last().unwrap()
}
}
fn main() {
let mut vec = vec![1, 2, 3];
f(&mut vec);
}
error[E0499]: cannot borrow `*vec` as mutable more than once at a time
--> src/main.rs:6:9
|
1 | fn f(vec: &mut Vec<u8>) -> &u8 {
| - let's call the lifetime of this reference `'1`
2 | if let Some(n) = vec.iter_mut().find(|n| **n == 1) {
| --- first mutable borrow occurs here
3 | *n = 10;
4 | n
| - returning this value requires that `*vec` is borrowed for `'1`
5 | } else {
6 | vec.push(10);
| ^^^ second mutable borrow occurs here
error[E0502]: cannot borrow `*vec` as immutable because it is also borrowed as mutable
--> src/main.rs:7:9
|
1 | fn f(vec: &mut Vec<u8>) -> &u8 {
| - let's call the lifetime of this reference `'1`
2 | if let Some(n) = vec.iter_mut().find(|n| **n == 1) {
| --- mutable borrow occurs here
3 | *n = 10;
4 | n
| - returning this value requires that `*vec` is borrowed for `'1`
...
7 | vec.last().unwrap()
| ^^^ immutable borrow occurs here
(NLLμ μν΄ κ³ μ λ NLLμ μ κ±° ν λ E-needstestλ₯Ό μ κ±° νμ΄μΌν©λλ€)
κ°μ₯ μ μ©ν λκΈ
λΆλ³μ μ°¨μ μ΄ λ무 μ€λ μ¬λ κ²μ²λΌ 보μ΄λ νλ‘λμ μμ λΉμ·ν λ¬Έμ κ° λ°μνλ€κ³ μκ°ν©λλ€ ( ν΄κ²° λ°©λ² ).
λν starwedμ μ½λ κ° λ μ΄μ μ΅μ μΌκ°μ μ»΄νμΌλμ§ μλλ€λ μ λ μΈκΈν΄μΌν©λλ€. @oberien μ "
regression-from-nightly-to-nightly
"νκ·Έλ₯Ό μ μνμΌλ©° μ΄κ²μ΄ κΈ΄κΈν λ¬Έμ μΈ κ²½μ° @nikomatsakis νκ·Έλ₯Ό λ°μμ΅λλ€ . :)