স্ট্রিংকে কীভাবে একটি & 'স্ট্যাটিক স্ট্রমে রূপান্তর করতে হয়


92

আমি কিভাবে একটি রূপান্তর না Stringএকটি মধ্যে &str? আরও সুনির্দিষ্টভাবে, আমি এটি আজীবন ( ) strদিয়ে রূপান্তর করতে চাই ।static&'static str


এটি সম্ভব বা কাম্য বলে মনে হচ্ছে না। 'staticজীবদ্দশায় বোঝা যাচ্ছে স্ট্রিংটি কখনও ক্ষয় করা হবে না, অর্থাত মেমরি ফুটো। কিছু উপযুক্তের &'static strপরিবর্তে আপনার প্রয়োজন কেন ? &'a str'a

4
তখন কীভাবে এটিকে রূপান্তর করতে দেখাবে &'a str ?
ক্রিস্টোফ

ভায়া as_slice। আপনি কোন কংক্রিট সমস্যা সমাধানের চেষ্টা করছেন এবং এমনটি করার সময় আপনি কোন সমস্যার মুখোমুখি হয়েছেন তা যদি বর্ণনা করেন তবে সহায়তা করা সহজ হবে।

এছাড়াও নোট করুন SendStr, একটি প্রকার যা হয় মালিকানাযুক্ত স্ট্রিং বা স্ট্যাটিক স্ট্রিং।
ক্রিস মরগান

উত্তর:


135

মরিচ 1.0 এর জন্য আপডেট হয়েছে

আপনি কোনও &'static strথেকে অর্জন করতে পারবেন না Stringকারণ Stringআপনার প্রোগ্রামের পুরো জীবন ধরে না থাকতে পারে এবং &'staticআজীবন এর অর্থ। আপনি Stringএটি থেকে নিজের জীবনকাল দ্বারা প্যারামিটারাইজড কেবল একটি স্লাইস পেতে পারেন ।

একটি Stringথেকে স্লাইসে যেতে &'a strআপনি স্লাইসিং সিনট্যাক্স ব্যবহার করতে পারেন:

let s: String = "abcdefg".to_owned();
let s_slice: &str = &s[..];  // take a full slice of the string

বিকল্পভাবে, আপনি একটি বাস্তব পুনর্বিবেচনার Stringপ্রয়োগ Deref<Target=str>এবং সম্পাদন করেন এমন সত্যটি ব্যবহার করতে পারেন :

let s_slice: &str = &*s;  // s  : String 
                          // *s : str (via Deref<Target=str>)
                          // &*s: &str

আরও একটি উপায় রয়েছে যা আরও সংক্ষিপ্ত সিনট্যাক্সের অনুমতি দেয় তবে এটি কেবল তখনই ব্যবহার করা যেতে পারে যখন সংকলক পছন্দসই লক্ষ্য প্রকারটি নির্ধারণ করতে সক্ষম হয় (উদাহরণস্বরূপ ফাংশন আর্গুমেন্টে বা স্পষ্টত টাইপযুক্ত ভেরিয়েবল বাইন্ডিংগুলিতে)। একে ডেরেফ কোর্সিওন বলা হয় এবং এটি কেবল &অপারেটর ব্যবহারের অনুমতি দেয় এবং সংকলক স্বয়ংক্রিয়ভাবে *প্রসঙ্গের ভিত্তিতে একটি উপযুক্ত পরিমাণ সন্নিবেশ করবে :

let s_slice: &str = &s;  // okay

fn take_name(name: &str) { ... }
take_name(&s);           // okay as well

let not_correct = &s;    // this will give &String, not &str,
                         // because the compiler does not know
                         // that you want a &str

লক্ষ্য করুন এই প্যাটার্ন জন্য অনন্য নয় String/ &str- আপনি যার মাধ্যমে সংযুক্ত আছেন ধরনের প্রতিটি যুগল সঙ্গে এটি ব্যবহার করতে পারেন Deref, উদাহরণস্বরূপ, সঙ্গে CString/ CStrএবং OsString/ OsStrথেকে std::ffiমডিউল বা PathBuf/ Pathথেকে std::pathমডিউল।


29
মরিচা 1.10 এর পরিবর্তে let s_slice: &str = &s[..];আপনি কেবল এটি করতে পারেন:let s_slice: &str = s.as_str();
Shnatsel

4
কোনও এক সময়, string ... enough ব্লক ম্যাচের মতো আসল স্ট্রিং যথেষ্ট পরিমাণে বাস করে না। যে একটি হতে হবে 's' does not live long enough error
ডেরিকসন

42

আপনি এটি করতে পারেন, তবে এটির সাথে স্মৃতি ফাঁসString করা জড়িত । এটি আপনার হালকাভাবে করা উচিত নয়। Stringমেমোরি ফাঁস করার মাধ্যমে , আমরা গ্যারান্টি দিচ্ছি যে স্মৃতিটি কখনই মুক্ত হবে না (এভাবে ফুটো)। অতএব, অভ্যন্তরীণ অবজেক্টের কোনও রেফারেন্সকে 'staticজীবনকাল হিসাবে ব্যাখ্যা করা যেতে পারে ।

fn string_to_static_str(s: String) -> &'static str {
    Box::leak(s.into_boxed_str())
}

fn main() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let s: &'static str = string_to_static_str(s);
}

8
Stringএকটি গ্যারান্টি দেয়, যতক্ষণ না অবজেক্টটি ফেলে দেওয়া হয় না, স্মৃতিটি প্রাণবন্ত থাকে। যেহেতু mem::forgetগ্যারান্টি দেয় যে অবজেক্টটি কখনই বাদ দেওয়া হবে না, তাই আমাদের নিশ্চয়তা দেওয়া হয় যে এতে থাকা রেফারেন্সটি strকখনই অবৈধ হবে না। সুতরাং আমরা দৃ as়ভাবে বলতে পারি যে এটি একটি 'staticরেফারেন্স
দৃ as়ভাবে

4
এটা আমার মরচে আবেদন, যা একটি নিগৃহীত করা প্রয়োজন জন্য অবিশ্বাস্যভাবে সহায়ক ছিল Stringএকটি মধ্যে &'static strযাতে টোকেন মূল থেকে তৈরি Stringসকল লিপি জুড়ে উপলব্ধ হবে। এটি ছাড়া, মরিচা সংকলকটি অভিযোগ করবে যে আমার জীবনকালটি Stringমূল ফাংশন শেষে শেষ হয়েছিল যা যথেষ্ট ভাল ছিল না কারণ এর 'staticগ্যারান্টি নেই।
মিমস্টিক

4
@ মিমস্টিক: সেক্ষেত্রে আরও ভাল সমাধান crossbeam
হ'ল

4
@ মিমস্টিক: আপনি যদি আপনার পুরো অ্যাপ্লিকেশনটিকে ক্রসবিম স্কোপে রেখে দেন এবং সুযোগের বাইরে স্ট্রিং তৈরি করেন, আপনি ঠিক তা পেয়ে যাবেন।
oli_obk

4
এই উত্তর দুর্দান্ত! এটি উভয়ই আমাকে কীভাবে চূড়ান্তভাবে একটি স্ট্যাটিক স্ট্রিং স্লাইস তৈরি করতে এবং আমাকে তা না করার জন্য রাজি করিয়েছে তা বলেছিল! আমি অনেক জায়গায় স্থির স্ট্রিং স্লাইস ব্যবহার না করার জন্য আমার অ্যাপ্লিকেশনটিকে রিফ্যাক্টর বেছে নিয়েছি।
পল চেরনোক

24

মরিচা সংস্করণ 1.26 হিসাবে, এটি রূপান্তর করা সম্ভব String করতে &'static strব্যবহার না করেই unsafeকোড:

fn string_to_static_str(s: String) -> &'static str {
    Box::leak(s.into_boxed_str())
}

এটি Stringদৃষ্টান্তটিকে একটি বাক্সে রূপান্তরিত করে strঅবিলম্বে এটি ফাঁস করে। এটি স্ট্রিংটি বর্তমানে দখল করতে পারে এমন সমস্ত অতিরিক্ত ক্ষমতা মুক্ত করে।

মনে রাখবেন যে প্রায়শই এমন সমাধান রয়েছে যেগুলি ফাঁস হওয়া অবজেক্টগুলির চেয়ে পছন্দসই, যেমন crossbeamআপনি যদি থ্রেডগুলির মধ্যে রাষ্ট্র ভাগ করতে চান তবে ক্রেট ব্যবহার করুন ।


2

টিএল; ডিআর: আপনি নিজের &'static strথেকে একটি Stringযা পেতে পারেন'static জীবনকাল ।

যদিও অন্যান্য উত্তর সঠিক এবং সবচেয়ে দরকারী, একটি (তাই দরকারী নয়) প্রান্ত ক্ষেত্রে, যেখানে আপনি প্রকৃতপক্ষে একটি রূপান্তর করতে পারেন Stringএকটি থেকে&'static str :

একটি রেফারেন্সের আজীবন সর্বদা সংক্ষিপ্ত বা রেফারেন্সযুক্ত বস্তুর আজীবনের সমান হতে হবে। অর্থাত রেফারেন্সযুক্ত বস্তুর রেফারেন্সের চেয়ে দীর্ঘ (বা সমান দীর্ঘ) বাঁচতে হবে। যেহেতু 'staticকোনও প্রোগ্রামের পুরো জীবনকাল অর্থাত্, একটি দীর্ঘকালীন জীবদ্দশার অস্তিত্ব নেই। তবে একটি সমান আজীবন যথেষ্ট হবে। সুতরাং যদি Stringএকটির জীবনকাল থাকে তবে 'staticআপনি একটি পেতে পারেন&'static str এটি থেকে রেফারেন্স ।

বৈশিষ্ট্যটি প্রকাশিত হওয়ার পরে মুরগির সাথে 1.31 ব্যবহার করে তাত্ত্বিকভাবে staticএক ধরণের তৈরি করা Stringসম্ভব const fnহয়েছিল। দুর্ভাগ্যক্রমে, একমাত্র কনস্ট ফাংশনটি Stringহ'ল returningString::new() বর্তমানে, এবং এটি একটি বৈশিষ্ট্য গেট পিছনে এখনও (তাই মরচে রাত্রিকালীন এখন জন্য প্রয়োজন বোধ করা হয়)।

সুতরাং নিম্নলিখিত কোডটি কাঙ্ক্ষিত রূপান্তর করে (রাত্রে ব্যবহার করে) ... এবং আসলে এই প্রান্তের ক্ষেত্রে এটি সম্ভব কিনা তা দেখানোর সম্পূর্ণতা ব্যতীত আসলে কোনও ব্যবহারিক ব্যবহার নেই।

#![feature(const_string_new)]

static MY_STRING: String = String::new();

fn do_something(_: &'static str) {
    // ...
}

fn main() {
    do_something(&MY_STRING);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.