1

我在生命周期和借来的积分方面遇到了麻烦。我已经阅读了手册和借用的指针教程,但是......我仍然被卡住了。

素描main.rs

fn main() {
  let (db_child, repo_child):(DuplexStream<~str, ~str>, DuplexStream<~str, ~str>) = DuplexStream();
    do spawn {
        slurp_repos(&repo_child);
    }
}

素描repos.rs

fn slurp_repos(chan: &'static DuplexStream<~str, ~str>) {
    ...
    do request.begin |event| {
        ...
        chan.send(api_url);
    }
}

当我编译这些模块时, main.rs 有以下错误:

main.rs:21:20: 21:31 error: borrowed value does not live long enough
main.rs:21         slurp_repos(&repo_child);
                               ^~~~~~~~~~~
note: borrowed pointer must be valid for the static lifetime...
main.rs:13:10: 1:0 note: ...but borrowed value is only valid for the block at 13:10
error: aborting due to previous error

我不太清楚如何声明我的 DuplexStreams 生命周期静态。或者这可能是 slurp_repos 函数类型的错误方法。

如果您想查看完整的上下文:

4

1 回答 1

1

我无法测试,但我想解决方案是将repo_child流移动到slurp_repos,即:

fn main() {
  let (db_child, repo_child) = DuplexStream();
    do spawn {
        slurp_repos(repo_child);
    }
}

fn slurp_repos(chan: DuplexStream<~str, ~str>) {
    ...
    do request.begin |event| {
        ...
        chan.send(api_url);
    }
}

通过移动整个端点,它允许它跨任务传输(因为 aDuplexStream能够Send)。另外,请注意共享(使用引用允许的)基本双向流的端点(这是什么DuplexStream)并没有真正意义:电话的每一端只能有一个人。

repo_child关于活得不够长的错误消息是因为类型slurp_repos需要'static在程序的整个生命周期中持续存在,但repo_child绝对不会:它是函数的局部变量。

编译器告诉你穿上的原因'staticslurp_repos是因为唯一Send能够引用的是具有此生命周期的引用。这个限制是必需的,因为您可以在借用任务之前完成拥有任务,然后销毁/释放引用,留下一个悬空指针;在图表中:

start program/call main
  |
  v
allocate repo_child
  |
  v
spawn -----------------> slurp_repos(chan = &repo_child)
  |                          |
  v                          v
finish                   do things with the chan reference to repo_child
  |                          |
  v                          v
deallocate repo_child    general work ...
                             |
                             v
                         do more things with chan: 
                           oops, already freed; use-after-free bug
于 2013-07-27T14:05:31.303 回答