난 그냥 몇 가지 세부 사항은 현재 다르기 때문에 나는이 질문을 다시 거라고 생각 허용하지 않을 것입니다.(솔직히 말해서, 난 그냥이 나 자신을 이해하지 않기 때문에 나는이 물건에 파고 내 결과를 기록하기로 결정했다.)
우리는이 코드로 시작 : 여기
use std::io::{stdin, BufRead};
fn main() {
for l in stdin().lock().lines() {
println!("{}", l.unwrap());
}
}
것은 무엇 컴파일러 대답했습니다이 여전히 하시다하지 않습니다
fn main() {
let lock = stdin().lock();
}
:
t.rs:4:14: 4:21 error: borrowed value does not live long enough
t.rs:4 for l in stdin().lock().lines() {
^~~~~~~
t.rs:4:5: 6:6 note: reference must be valid for the destruction scope surrounding statement at 4:4...
t.rs:4 for l in stdin().lock().lines() {
t.rs:5 println!("{}", l.unwrap());
t.rs:6 }
t.rs:4:5: 6:6 note: ...but borrowed value is only valid for the statement at 4:4
t.rs:4 for l in stdin().lock().lines() {
t.rs:5 println!("{}", l.unwrap());
t.rs:6 }
t.rs:4:5: 6:6 help: consider using a `let` binding to increase its lifetime
이의 간단 뭔가를 해보자 rk이고 오류는 매우 비슷합니다. 이것이 작동하지 않는다는 사실은 문제가 stdin()
전화와 함께 있음을 말해줍니다.
t.rs:4:16: 4:23 error: borrowed value does not live long enough
t.rs:4 let lock = stdin().lock();
^~~~~~~
t.rs:3:11: 5:2 note: reference must be valid for the block at 3:10...
t.rs:3 fn main() {
t.rs:4 let lock = stdin().lock();
t.rs:5 }
t.rs:4:5: 4:31 note: ...but borrowed value is only valid for the statement at 4:4
t.rs:4 let lock = stdin().lock();
^~~~~~~~~~~~~~~~~~~~~~~~~~
t.rs:4:5: 4:31 help: consider using a `let` binding to increase its lifetime
유형을 살펴 보겠습니다. .lock
방법이있다 stdin
반환 Stdin
:
fn lock(&self) -> StdinLock
메서드의 반환 형식이 StdinLock
,하지만 당신은 그 선언을 보면, 당신이 평생 매개 변수를 사용하는 것을 볼 수 있습니다 :
pub struct StdinLock<'a> {
// some fields omitted
}
을
생략 된 필드가이 매개 변수의 이유이며, sources을 참조하여 MutexGuard
이 있음을 알게되고, 유효 기간이 가드 내부에 저장된 값의 유형에 적용됩니다. 그러나 그것은 실제로 전혀 중요하지 않습니다.
fn lock<'a>(&'a self) -> StdinLock<'a> /* Self = Stdin */
겠어요 - : 포인트가 포함 lifetime elision 있다는 것을 의미이 유효 기간 파라미터, 및 lock
방법 선언 인이 실제로 있다는 로컬 lock
변수의 유형은 StdinLock<'a>
입니다. 이 'a
유형의 매개 변수는 StdinLock
내부에 최소한 'a
에 유효해야하는 참조가 있음을 의미합니다. 반면에 lock
이 우리 함수의 지역 변수라는 사실로부터 우리는 범위가이 함수의 본문임을 알고 있고 그 유형이 StdinLock<'a>
이라는 사실로부터 컴파일러는 'a
이 본문에 해당하는 범위라고 결론을 내립니다 함수의.
우리가 깨달을 때이 시점에서의 그는 유형 값에 의해 반환라고 우리에게 이야기하기 때문에, 전체 함수 본문 살아 있어야한다에 전달 가져옵니다 self
인수 유효 할 .lock()
에 호출 .lock()
은 그 일부에 대한 일부 참조를 유지합니다. 그러나 우리가 명시 적으로을 사용하면 let
을 사용하면 수명이 길어지기 때문에 계산서가 끝나면 즉시 폐기됩니다. 발생
use std::io::{stdin, BufRead};
fn main() {
let stdin = stdin();
for l in stdin.lock().lines() {
println!("{}", l.unwrap());
}
}
가 작동 :
우리는 가진 끝.
항상 그렇듯이 모든 것이 소유권 문제로 귀결됩니다. .lock()
에서 반환 된 값은 호출 된 항목의 소유권을 가지지 않지만 (이 경우에는 stdin()
의 결과 임) 참조를 유지합니다.즉, stdin()
의 결과를 유지하는 책임을 맡고 누군가가 당신을 (그리고 나)해야한다는 것을 의미합니다. 다른 옵션은 없으므로 누군가가 당신이되어야합니다.).
한편 , .lines()
의 유형이있다 :
fn lines(self) -> Lines<Self> /* Self = StdinLock */
당신은 self
을 소모하기 때문에 값에서 반환 우리가 명시 적으로 .lock()
의 결과를 결합하지 않아도 볼 수 있듯이 .lines()
은 자물쇠의 소유권을 취하므로 필요에 따라 그것을 유지 한 다음 파기해야 할 책임이 있습니다.
좋습니다. "수명 매개 변수가있는 중간 값이 문 끝에서 중단됨"을 수락합니다. 수명에 대해 조금 더 읽어야합니다. 하지만 : "중간 값 사용"이 실제로 이것을 해결하는 방법입니까? ... 중복 해결 방법과 비슷합니다. – forgemo
지금은 아마도 추론 알고리즘이 수명까지 연장 될 수 있지만 기능적이지 않은 주된 이유가 있습니다. 특히 암시 적보다 낫습니다. –
자바, 스칼라, haskell 또는 다트 등 주요 "상위 수준"언어에서 오는 ....이 행동은 나에게 매우 "방해"것 같습니다. 이런 식으로 좀 더 복잡한 코드를 개발하는 것이 얼마나 성가신 일인지 상상할 수 없습니다. 조만간이 문제를 해결하기 바랍니다. 도와 주셔서 감사합니다! – forgemo