2015-05-31 18 views
7

मैं वर्तमान में जंग (1.0) में जीवनकाल के साथ संघर्ष कर रहा हूं, खासकर जब चैनलों के माध्यम से structs पास करने की बात आती है।मैं धागे के साथ स्थिर जीवनकाल का उपयोग कैसे करूं?

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 केवल for में से एक यात्रा के लिए रहता है), लेकिन मैं यह पता नहीं लगा सकता कि ऐसा करने का सही तरीका क्या है।

  • मैं, संकलक संकेत के रूप में, &'static str में &str बदलने की कोशिश करनी चाहिए?
  • क्या मैं स्मृति को लीक कर रहा हूं यदि प्रत्येक पंक्ति में 'static जीवनकाल होगा?
  • मुझे 'static का उपयोग कब करना चाहिए? क्या यह कुछ है जो मुझे टालने का प्रयास करना चाहिए या यह बिल्कुल ठीक है?
  • क्या चैनलों के माध्यम से structs में String एस पास करने का कोई बेहतर तरीका है?

मैं उन बेवकूफ सवालों के लिए क्षमा चाहता हूं। मैंने पहले से ही कुछ समय खोज कर बिताया है, लेकिन मैं इसके चारों ओर अपने सिर को लपेट नहीं सकता। यह शायद मेरी गतिशील भाषा पृष्ठभूमि रास्ते में हो रही है :)

एक तरफ के रूप में: &input[..]String को &str में परिवर्तित करने के लिए ठीक है? यह एकमात्र स्थिर तरीका है जिसे मैं ऐसा करने के लिए पा सकता हूं।

उत्तर

11

आप स्मृति को लीक करके &'a T&'static T में परिवर्तित नहीं कर सकते हैं। सौभाग्य से, यह बिल्कुल जरूरी नहीं है। उधार पॉइंटर्स को धागे में भेजने और लाइनों को मुख्य धागे पर रखने का कोई कारण नहीं है। आपको मुख्य धागे पर लाइनों की आवश्यकता नहीं है। बस लाइनों को स्वयं भेजें, यानी String भेजें।

तो एक से अधिक थ्रेड से पहुँच था आवश्यक (और आप क्लोन करने के लिए नहीं करना चाहते हैं), का उपयोग Arc<String> (भविष्य में, Arc<str> भी काम कर सकते हैं)। इस तरह स्ट्रिंग को थ्रेड, के बीच साझा किया जाता है, ठीक से साझा किया जाता है, ताकि जब कोई धागा इसका उपयोग नहीं करता है तो इसे ठीक से हटा दिया जाएगा।

गैर-'static भेजना धागे के बीच संदर्भ असुरक्षित है क्योंकि आप कभी नहीं जानते कि अन्य धागा इसका उपयोग कब तक जारी रखेगा, इसलिए आपको नहीं पता कि उधार समाप्त होने पर और वस्तु को मुक्त किया जा सकता है। ध्यान दें कि स्कॉप्ड थ्रेड्स में यह समस्या नहीं है (जो 1.0 में नहीं हैं लेकिन हम बोलते समय फिर से डिजाइन किए जा रहे हैं) इसे अनुमति दें, लेकिन नियमित, spawn एड थ्रेड करते हैं।

'static ऐसा कुछ नहीं है जिसे आप टालना चाहिए, यह जो कुछ भी करता है उसके लिए यह बिल्कुल ठीक है: यह बताते हुए कि पूरे अवधि के लिए एक कार्यक्रम रहता है, कार्यक्रम चल रहा है। लेकिन अगर वह नहीं है जो आप व्यक्त करने की कोशिश कर रहे हैं, निश्चित रूप से यह गलत उपकरण है।

+0

ओह, ठीक है। यह एक आसान समाधान है। 'स्ट्रक्चर' में 'स्ट्रिंग' के साथ' & str' को प्रतिस्थापित करना चाल है। धन्यवाद, मुझे वास्तव में पहले कोशिश करनी चाहिए थी। – marekventur

संबंधित मुद्दे