মরিচের `স্ট্রিং` এবং` str` এর মধ্যে পার্থক্য কী?


418

মরিচা কেন Stringএবং আছে str? Stringএবং মধ্যে পার্থক্য কি str? এর Stringপরিবর্তে strএবং বিপরীতে যখন কোনটি ব্যবহার করে ? তাদের মধ্যে কি একজনের অবমূল্যায়ন হচ্ছে?

উত্তর:


488

Stringডায়নামিক হিপ স্ট্রিং টাইপ, যেমন Vec: আপনার স্ট্রিং ডেটার মালিকানা বা পরিবর্তন করার দরকার হলে এটি ব্যবহার করুন।

strমেমরির কোথাও গতিশীল দৈর্ঘ্যের ইউটিএফ -8 বাইটের একটি অপরিবর্তনীয় 1 ক্রম। যেহেতু আকারটি অজানা, কেউ কেবল এটি পয়েন্টারের পিছনে পরিচালনা করতে পারে। এর অর্থ হল যে strসর্বাধিক 2 হিসাবে প্রদর্শিত হয় &str: কিছু ইউটিএফ -8 ডেটার রেফারেন্স, সাধারণত একটি "স্ট্রিং স্লাইস" বা কেবল একটি "স্লাইস" নামে পরিচিত। একটি স্লাইস কিছু ডেটাতে কেবল একটি ভিউ এবং এটি ডেটা যে কোনও জায়গায় যেমন হতে পারে

  • স্ট্যাটিক স্টোরেজে : একটি স্ট্রিং আক্ষরিক "foo"হয় &'static str। প্রোগ্রামটি সঞ্চালনের সময় ডেটা হার্ডকোড করা হয় এবং মেমরিতে লোড হয়।
  • বরাদ্দ করা একটি স্তূপের অভ্যন্তরেString : এর ডেটা দেখার জন্য Stringশ্রদ্ধা&strString
  • স্ট্যাকের উপর : উদাহরণস্বরূপ নিম্নলিখিতটি একটি স্ট্যাক-বরাদ্দ করা বাইট অ্যারে তৈরি করে এবং তারপরে সেই ডেটাটির একটি হিসাবে একটি ভিউ&str পায় :

    use std::str;
    
    let x: &[u8] = &[b'a', b'b', b'c'];
    let stack_str: &str = str::from_utf8(x).unwrap();

সংক্ষেপে, Stringআপনার যদি মালিকানাধীন স্ট্রিং ডেটা প্রয়োজন হয় (যেমন অন্য থ্রেডগুলিতে স্ট্রিংগুলি প্রেরণ করা, বা রানটাইমগুলিতে এগুলি তৈরি করা) ব্যবহার করুন এবং &strআপনার কেবল স্ট্রিংয়ের ভিউ প্রয়োজন হলে ব্যবহার করুন ।

এটি একটি ভেক্টর Vec<T>এবং স্লাইসের &[T]মধ্যে সম্পর্কের অনুরূপ Tএবং &Tসাধারণ ধরণের জন্য বাই-ভ্যালু এবং বাই রেফারেন্সের সম্পর্কের মতো similar


1strস্থির দৈর্ঘ্য; আপনি শেষের বাইরে বাইট লিখতে পারবেন না, বা অবৈধ বাইটগুলি অনুসরণ করতে পারবেন না। যেহেতু ইউটিএফ -8 একটি পরিবর্তনশীল-প্রস্থের এনকোডিং, এটি কার্যকরভাবে সমস্ত strক্ষেত্রে অনেক ক্ষেত্রে অপরিবর্তনীয় হতে বাধ্য করে । সাধারণভাবে, মিউটেশনের জন্য আগের তুলনায় আরও বা কম বাইট লেখার প্রয়োজন হয় (যেমন একটি a(1 বাইট) প্রতিস্থাপনের সাথে ä(2+ বাইট) আরও বেশি জায়গা তৈরি করতে হবে str)। নির্দিষ্ট পদ্ধতি রয়েছে যা &strস্থানে একটি পরিবর্তন করতে পারে , বেশিরভাগ সেগুলি কেবলমাত্র ASCII অক্ষর যেমন পরিচালনা করে make_ascii_uppercase

2 গতিশীল আকারের ধরণের জিনিসগুলি Rc<str>মরিচা 1.2 এর পর থেকে ইউটিএফ -8 বাইট গণনা রেফারেন্সের ক্রমের জন্য পছন্দ করে । মরিচা 1.21 সহজেই এই ধরণের তৈরি করতে দেয়।


10
"ইউটিএফ -8 বাইটের ক্রম ( অজানা দৈর্ঘ্যের )" - এটি কি পুরানো? ডক্স বলে "একজন &strদুই উপাদান গঠিত: কিছু বাইট একটি পয়েন্টার, এবং একটি দৈর্ঘ্য।"
এমআরসিসি

11
এটি তারিখের বাইরে নেই (এটি উপস্থাপনাটি মোটামুটি স্থিতিশীল হয়েছে), কেবলমাত্র সামান্য ত্রুটিযুক্ত: এটি স্ট্যাটিকালি জানা যায় না, বলার অপেক্ষা রাখে না [u8; N]
Huon

2
কমপ্লেক্সের সময় এটি ইমরেক অজানা, আকারের সম্পর্কে অনুমানগুলি তৈরি করা যায় না, উদাহরণস্বরূপ, স্ট্যাক ফ্রেম তৈরি করার সময়। সুতরাং কেন এটি প্রায়শই একটি রেফারেন্স হিসাবে বিবেচনা করা হয়, যা সংকলনের সময় একটি রেফারেন্স একটি পরিচিত আকার, যা কোনও পয়েন্টারের আকার।
সেখাত

1
আপডেট: Rc<str>এবং Arc<str>এখন স্ট্যান্ডার্ড লাইব্রেরির মাধ্যমে ব্যবহারযোগ্য।
সেন্ট্রিল

1
@ কেজোহানসন স্ট্যাটিক্যালি বরাদ্দকৃত অবজেক্টগুলি সাধারণত গাদা বা স্ট্যাকের মধ্যে সংরক্ষণ করা হয় না, তবে তাদের নিজস্ব স্মৃতি অঞ্চলে থাকে।
ব্রেনান ভিনসেন্ট

96

আমার একটি সি ++ ব্যাকগ্রাউন্ড রয়েছে এবং আমি সি ++ পদগুলির সম্পর্কে Stringএবং &strএটি ভাবতে খুব দরকারী বলে মনে করি :

  • একটি মরিচা Stringএকটি মত std::string; এটি মেমরির মালিক এবং মেমরি পরিচালনা করার নোংরা কাজ করে।
  • একটি মরিচা ( &strযেমন char*কিছুটা পরিশীলিত); এটি একইভাবে একটি খণ্ডের শুরুতে আমাদেরকে নির্দেশ করে আপনি সামগ্রীর সামগ্রীতে একটি পয়েন্টার পেতে পারেন std::string

তাদের মধ্যে কি অদৃশ্য হয়ে যাচ্ছে? আমি এমন মনে করি না. তারা দুটি উদ্দেশ্য পরিবেশন করে:

Stringবাফার রাখে এবং ব্যবহার করা খুব ব্যবহারিক। &strএটি হালকা ওজনের এবং স্ট্রিংগুলিতে "চেহারা" ব্যবহার করা উচিত। আপনি নতুন মেমরি বরাদ্দের প্রয়োজন ছাড়াই অনুসন্ধান করতে পারবেন, ভাগ করতে পারবেন, পার্স করতে পারবেন এবং এমনকি অংশগুলি প্রতিস্থাপন করতে পারেন।

&strStringএটি কোনও স্ট্রিং আক্ষরিকের দিকে ইঙ্গিত করতে পারে তার ভিতরে দেখতে পারে। নিম্নলিখিত কোডটিতে আক্ষরিক স্ট্রিংটি Stringপরিচালিত মেমোরিতে অনুলিপি করা দরকার :

let a: String = "hello rust".into();

নিম্নলিখিত কোডটি আপনাকে অনুলিপি ছাড়াই আক্ষরিক ব্যবহার করতে দেয় (কেবল পঠনযোগ্য)

let a: &str = "hello rust";

12
একটি স্ট্রিং_ ভিউ মত?
অভিনব গৌনিয়াল

1
হ্যাঁ স্ট্রিং_ ভিউয়ের মতো তবে ভাষার অভ্যন্তরীণ এবং যথাযথভাবে ধার করা হয়েছে।
লোককা

41

str, কেবল হিসাবে ব্যবহৃত &str, এটি একটি স্ট্রিং স্লাইস, কোনও ইউটিএফ -8 বাইট অ্যারের রেফারেন্স।

Stringযা ব্যবহৃত ~strহত, বর্ধনযোগ্য, মালিকানাধীন ইউটিএফ -8 বাইট অ্যারে।


প্রযুক্তিগতভাবে, ~strএখন যা ব্যবহৃত হত তা হলBox<str>
jv110

3
@ jv110: না, কারণ ~strবর্ধনযোগ্য ছিল এবং বর্ধনযোগ্য Box<str>নয়। (এটি ~strএবং ~[T]যাদুকরভাবে বিকাশযোগ্য, অন্য কোনও উদ্দেশ্য থেকে ~পৃথক, ঠিক কারণেই Stringএবং Vec<T>প্রবর্তন করা হয়েছিল, যাতে নিয়মগুলি সমস্ত সোজা এবং সামঞ্জস্যপূর্ণ ছিল))
ক্রিস মরগান

18

এগুলি আসলে সম্পূর্ণ আলাদা। প্রথমত, strএকটি ধরণের স্তরের জিনিস ছাড়া কিছুই নয়; এটি কেবল ধরণের স্তরে যুক্তিযুক্ত হতে পারে কারণ এটি একটি তথাকথিত গতিশীল আকারের টাইপ (ডিএসটি)। strসংকলনের সময় গ্রহণের আকারটি জানা যায় না এবং এটি রানটাইম তথ্যের উপর নির্ভর করে - এটি কোনও চলকটিতে সংরক্ষণ করা যায় না কারণ সংকলকটি প্রতিটি ভেরিয়েবলের আকার কী তা সংকলনের সময় জানতে হবে। একটি strধারণার দিক থেকে শুধু একটি সারি u8গ্যারান্টি এটি ফর্ম বৈধ হল UTF-8 সঙ্গে বাইট। সারি কত বড়? রানটাইম অবধি কেউ জানে না তাই এটি কোনও ভেরিয়েবলে সংরক্ষণ করা যায় না।

মজার বিষয় করে একটি হল &strএকটি অথবা অন্য কোন পয়েন্টার strমত Box<str> করে রানটাইম এ বিদ্যমান। এটি একটি তথাকথিত "ফ্যাট পয়েন্টার"; এটি অতিরিক্ত তথ্যের সাথে একটি পয়েন্টার (এক্ষেত্রে এটি যে জিনিসটির দিকে নির্দেশ করছে তার আকার) তাই এটি দ্বিগুণ হয়ে যায়। আসলে, একটি &strএকটি এর খুব কাছাকাছি String(তবে এটির সাথে নয় &String)। ক &strদুটি শব্দ; একটিটির প্রথম বাইটে একটি পয়েন্টার strএবং অন্য একটি সংখ্যার মধ্যে কতগুলি বাইট দীর্ঘ হয় তা বর্ণনা করে str

যা বলা হয় তার বিপরীতে, strএটিকে অপরিবর্তনীয় হওয়ার দরকার নেই। আপনি যদি এর &mut strএকচেটিয়া পয়েন্টার হিসাবে পেতে পারেন তবে আপনি strএটিকে পরিবর্তন করতে পারেন এবং এটির পরিবর্তিত সমস্ত সুরক্ষিত ফাংশনগুলি গ্যারান্টি দেয় যে ইউটিএফ -8 সীমাবদ্ধতা বহাল রয়েছে কারণ যদি এটি লঙ্ঘন করা হয় তবে গ্রন্থাগারটি আমাদের এই বাধ্যবাধকতা হিসাবে ধরে নিয়েছে কারণ আমাদের অনির্ধারিত আচরণ রয়েছে সত্য এবং এটি পরীক্ষা করে না।

সুতরাং একটি কি String? এটি তিনটি শব্দ; দুটি একই হিসাবে &strতবে এটি একটি তৃতীয় শব্দ যুক্ত করে যা strগাদাতে বাফারের সক্ষমতা , সর্বদা গাদাতে থাকে ( strএ গর্তের উপর অগত্যা নয়) এটি পূরণ হওয়ার আগে পুনরায় বরাদ্দ করতে হয়। Stringমূলত মালিক একটি strতারা যা বলে; এটি এটিকে নিয়ন্ত্রণ করে এবং এর আকার পরিবর্তন করতে এবং উপযুক্ত দেখা গেলে পুনরায় সেট করতে পারে। সুতরাং একটি Stringহিসাবে কাছাকাছি &strএকটি বলা হয় str

আর একটি বিষয় হ'ল ক Box<str>; এটিও একটি মালিক strএবং তার রানটাইম উপস্থাপনা একটি হিসাবে একই &strকিন্তু এটি মালিক strঅসদৃশ &strকিন্তু তা মাপ পরিবর্তন করতে পারবেন না কারণ এটা তার ধারণক্ষমতা তাই মূলত একটি জানে না Box<str>একটি নির্দিষ্ট দৈর্ঘ্যের হিসেবে দেখা যেতে পারে Stringআপনি যা করতে পারেন যে মাপ পরিবর্তন করা যাবে না ( Stringআপনি যদি এটির আকার পরিবর্তন করতে চান তবে সর্বদা এটিতে রূপান্তর করুন )।

কোনও ইউটিএফ -8 সীমাবদ্ধতা ছাড়া [T]এবং এর মধ্যে একটি খুব অনুরূপ সম্পর্ক বিদ্যমান Vec<T>এবং এটি কোনও ধরণের ধারণ করতে পারে যার আকার গতিশীল নয়।

strধরণের স্তরের ব্যবহার বেশিরভাগ ক্ষেত্রে জেনেরিক বিমূর্ততা তৈরি করতে হয় &str; এটি সুবিধামত বৈশিষ্ট্যগুলি লিখতে সক্ষম হতে টাইপ স্তরে উপস্থিত রয়েছে। তত্ত্ব strহিসাবে একটি প্রকারের জিনিসটির অস্তিত্বের প্রয়োজন ছিল না এবং কেবল &strতার অর্থ অনেকগুলি অতিরিক্ত কোড লিখতে হবে যা এখন জেনেরিক হতে পারে।

&strStringঅনুলিপি ব্যতীত একাধিক বিভিন্ন সাবস্ট্রিং থাকতে সক্ষম হ'তে অতি দরকারী ; হিসাবে একটি বলল String মালিকstr গাদা এটা পরিচালনা করে এবং যদি আপনি শুধুমাত্র একটি একটি সাবস্ট্রিং তৈরী করতে পারে Stringএকটি নতুন সঙ্গে Stringএটা কপি কারণ মরচে সবকিছু ওনলি মেমোরি নিরাপত্তা সঙ্গে মোকাবিলা করার জন্য একটি একক মালিক থাকতে পারে করতে হবে। সুতরাং উদাহরণস্বরূপ আপনি একটি স্ট্রিং টুকরা করতে পারেন:

let string: String   = "a string".to_string();
let substring1: &str = &string[1..3];
let substring2: &str = &string[2..4];

আমাদের কাছে strএকই স্ট্রিংয়ের দুটি পৃথক স্ট্রিং রয়েছে। stringহ'ল প্রকৃত পুরো strবাফারটির মালিক হ'ল &strসাব - স্ট্রিংগুলি হ'ল বাফারে কেবল ফ্যাট পয়েন্টার।


4

std::Stringকেবল একটি ভেক্টর u8। আপনি উত্স কোডে এর সংজ্ঞাটি পেতে পারেন । এটি গাদা বরাদ্দ এবং বিকাশযোগ্য।

#[derive(PartialOrd, Eq, Ord)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct String {
    vec: Vec<u8>,
}

strএটি একটি আদিম প্রকার, একে স্ট্রিং স্লাইসও বলা হয় । একটি স্ট্রিং স্লাইসের স্থির আকার রয়েছে। মত একটি আক্ষরিক স্ট্রিং let test = "hello world"হয়েছে &'static strপ্রকার। testএই স্থিতি বরাদ্দ স্ট্রিংয়ের একটি রেফারেন্স। &strপরিবর্তন করা যায় না, উদাহরণস্বরূপ,

let mut word = "hello world";
word[0] = 's';
word.push('\n');

strপরিবর্তনীয় টুকরা আছে &mut str, উদাহরণস্বরূপ: pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str)

let mut s = "Per Martin-Löf".to_string();
{
    let (first, last) = s.split_at_mut(3);
    first.make_ascii_uppercase();
    assert_eq!("PER", first);
    assert_eq!(" Martin-Löf", last);
}
assert_eq!("PER Martin-Löf", s);

তবে ইউটিএফ -8 এ ছোট্ট পরিবর্তনটি তার বাইট দৈর্ঘ্য পরিবর্তন করতে পারে এবং একটি টুকরোটি তার পুনঃসমনকে পুনরায় স্থান দিতে পারে না।


0

সহজ কথায়, Stringহিটে (ঠিক যেমন Vec) ডেটাটাইপ সংরক্ষণ করা হয় এবং আপনার সেই অবস্থানটিতে অ্যাক্সেস থাকে।

&strএকটি স্লাইস টাইপ। এর অর্থ এটি হ'ল Stringকোথাও কোথাও একটি ইতিমধ্যে উপস্থিত রেফারেন্স ।

&strরানটাইমে কোনও বরাদ্দ না করে। সুতরাং, মেমরির কারণে, আপনি &strওভার ব্যবহার করতে পারেন String। তবে, মনে রাখবেন যে ব্যবহার করার সময় &strআপনাকে সুস্পষ্ট লাইফ টাইম মোকাবেলা করতে হতে পারে।


1
কোথাও গাদা - এটি সম্পূর্ণ সঠিক নয়।
শেপমাস্টার

আমি যা বোঝাতে চেয়েছি তা strহ'ল viewইতিমধ্যে উপস্থিত Stringap
00imvj00

1
আমি বুঝতে পেরেছি আপনি যা বোঝাতে চেয়েছিলেন, আমি বলছি যে এটি সম্পূর্ণ সঠিক নয়। "গাদা" বিবৃতিটির প্রয়োজনীয় অংশ নয়।
শেপমাস্টার

-1

সি # এবং জাভা লোকের জন্য:

  • মরিচা ' String===StringBuilder
  • মরিচা &str === (অপরিবর্তনীয়) স্ট্রিং

আমি &strজাভা / সি # তে অভ্যন্তরীণ স্ট্রিংয়ের মতো একটি স্ট্রিংয়ের মতামত হিসাবে ভাবতে চাই যেখানে আপনি এটি পরিবর্তন করতে পারবেন না, কেবল একটি নতুন তৈরি করুন।


1
জাভা / সি # স্ট্রিং এবং মরিচা স্ট্রিংগুলির মধ্যে সবচেয়ে বড় পার্থক্য হ'ল মর্টটি স্ট্রিংটিকে সঠিক ইউনিকোড হওয়ার জন্য গ্যারান্টি দেয়, যেমন একটি স্ট্রিংয়ে তৃতীয় চরিত্র পাওয়ার জন্য কেবল "এবিসি" [২] এর চেয়ে বেশি চিন্তাভাবনা প্রয়োজন। (আমরা বহু ভাষাগুলি বিশ্বে বাস করি, এটি ভাল জিনিস))
কাঠবিড়ালি

এটি ভুল । ইতোমধ্যে শীর্ষস্থানীয় উত্তরের উত্তরে পরিবর্তনের বিষয়টিকে সম্বোধন করা হয়েছে; আরও জানতে এটি পড়ুন।
শেপমাস্টার

-5

এখানে একটি দ্রুত এবং সহজ ব্যাখ্যা।

String- একটি বর্ধনযোগ্য, মালিকানাযোগ্য হিপ-বরাদ্দ করা ডেটা কাঠামো। এটি একটি জোর করা যেতে পারে &str

str- (এখন, মরিচা বিকশিত হওয়ার সাথে সাথে) পরিবর্তনযোগ্য, স্থির-দৈর্ঘ্যের স্ট্রিং যা গাদা বা বাইনারিগুলিতে থাকে। আপনি কেবল strস্ট্রিং স্লাইস ভিউয়ের মাধ্যমে ধার করা ধরণের হিসাবে ইন্টারেক্ট করতে পারেন , যেমন &str

ব্যবহার বিবেচনা:

Stringআপনি যদি স্ট্রিংটির মালিকানা বা রূপান্তর করতে চান তবে পছন্দ করুন - যেমন স্ট্রিংটিকে অন্য থ্রেডে পাস করা ইত্যাদি etc.

&strআপনি যদি স্ট্রিংয়ের কেবল পঠনযোগ্য দর্শন পেতে চান তবে অগ্রাধিকার দিন ।


এটি ভুল । ইতোমধ্যে শীর্ষস্থানীয় উত্তরের উত্তরে পরিবর্তনের বিষয়টিকে সম্বোধন করা হয়েছে; আরও জানতে এটি পড়ুন।
শেপমাস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.