12

私は現在、特にチャネルを介して構造体を渡す場合に、Rust (1.0) のライフタイムに苦労しています。

この簡単な例をコンパイルするにはどうすればよいですか。

use std::sync::mpsc::{Receiver, Sender};
use std::sync::mpsc;
use std::thread::spawn;
use std::io;
use std::io::prelude::*;

struct Message<'a> {
    text: &'a str,
}

fn main() {
    let (tx, rx): (Sender<Message>, Receiver<Message>) = mpsc::channel();

    let _handle_receive = spawn(move || {
        for message in rx.iter() {
            println!("{}", message.text);
        }
    });

    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let message = Message {
            text: &line.unwrap()[..],
        };
        tx.send(message).unwrap();
    }
}

私は得る:

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:23:20
   |
23 |             text: &line.unwrap()[..],
   |                    ^^^^^^^^^^^^^ does not live long enough
...
26 |     }
   |     - temporary value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

lineこれが (の 1 回の反復でしか生きられない)理由はわかりますが、これforを行う正しい方法が何であるかはわかりません。

  • コンパイラが示唆するように、 を に変換する必要&strがあり&'static strますか?
  • 'staticすべての行に寿命がある場合、メモリをリークしていますか?
  • 'staticとにかくいつ使用することになっていますか?それは私が避けるべきものですか、それともまったく問題ありませんか?
  • Stringチャネル経由で構造体に sを渡すより良い方法はありますか?

素朴な質問で申し訳ありません。すでにかなりの時間をかけて検索しましたが、頭を包み込むことはできません。それはおそらく私の動的言語のバックグラウンドが邪魔をしているのです:)

余談ですが、a を考慮された OK&input[..]に変換するためのものですか? これは、これを行うために私が見つけることができる唯一の安定した方法です。String&str

4

2 に答える 2

15

メモリリーク以外では&'a T変換できません。&'static T幸いなことに、これはまったく必要ありません。借用したポインタをスレッドに送信し、メイン スレッドに行を保持する理由はありません。メインスレッドの行は必要ありません。行自体を送信するだけStringです。

複数のスレッドからのアクセス必要な場合 (クローンを作成したくない場合) は、Arc<String>(将来的にArc<str>は動作する可能性もあります) を使用します。このようにして、文字列はスレッド間で共有され、適切に共有されるため、スレッドがそれを使用しなくなったときに正確に割り当てが解除されます。

スレッド間で非参照を送信'staticすることは安全ではありません。なぜなら、他のスレッドがそれを使用し続ける期間がわからないためです。スコープスレッドにはこの問題がないことに注意してください(1.0 にはありませんが、私たちが話しているように再設計されています) がこれを許可しますが、通常のspawned スレッドは許可します。

'staticプログラムが実行されている間、値が存続することを示します。しかし、それがあなたが伝えようとしているものでない場合、もちろんそれは間違ったツールです。

于 2015-05-31T20:51:45.067 に答える