মরিচা কেন String
এবং আছে str
? String
এবং মধ্যে পার্থক্য কি str
? এর String
পরিবর্তে str
এবং বিপরীতে যখন কোনটি ব্যবহার করে ? তাদের মধ্যে কি একজনের অবমূল্যায়ন হচ্ছে?
মরিচা কেন String
এবং আছে str
? String
এবং মধ্যে পার্থক্য কি str
? এর String
পরিবর্তে str
এবং বিপরীতে যখন কোনটি ব্যবহার করে ? তাদের মধ্যে কি একজনের অবমূল্যায়ন হচ্ছে?
উত্তর:
String
ডায়নামিক হিপ স্ট্রিং টাইপ, যেমন Vec
: আপনার স্ট্রিং ডেটার মালিকানা বা পরিবর্তন করার দরকার হলে এটি ব্যবহার করুন।
str
মেমরির কোথাও গতিশীল দৈর্ঘ্যের ইউটিএফ -8 বাইটের একটি অপরিবর্তনীয় 1 ক্রম। যেহেতু আকারটি অজানা, কেউ কেবল এটি পয়েন্টারের পিছনে পরিচালনা করতে পারে। এর অর্থ হল যে str
সর্বাধিক 2 হিসাবে প্রদর্শিত হয় &str
: কিছু ইউটিএফ -8 ডেটার রেফারেন্স, সাধারণত একটি "স্ট্রিং স্লাইস" বা কেবল একটি "স্লাইস" নামে পরিচিত। একটি স্লাইস কিছু ডেটাতে কেবল একটি ভিউ এবং এটি ডেটা যে কোনও জায়গায় যেমন হতে পারে
"foo"
হয় &'static str
। প্রোগ্রামটি সঞ্চালনের সময় ডেটা হার্ডকোড করা হয় এবং মেমরিতে লোড হয়।String
: এর ডেটা দেখার জন্য String
শ্রদ্ধা&str
String
।স্ট্যাকের উপর : উদাহরণস্বরূপ নিম্নলিখিতটি একটি স্ট্যাক-বরাদ্দ করা বাইট অ্যারে তৈরি করে এবং তারপরে সেই ডেটাটির একটি হিসাবে একটি ভিউ&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
1 এ str
স্থির দৈর্ঘ্য; আপনি শেষের বাইরে বাইট লিখতে পারবেন না, বা অবৈধ বাইটগুলি অনুসরণ করতে পারবেন না। যেহেতু ইউটিএফ -8 একটি পরিবর্তনশীল-প্রস্থের এনকোডিং, এটি কার্যকরভাবে সমস্ত str
ক্ষেত্রে অনেক ক্ষেত্রে অপরিবর্তনীয় হতে বাধ্য করে । সাধারণভাবে, মিউটেশনের জন্য আগের তুলনায় আরও বা কম বাইট লেখার প্রয়োজন হয় (যেমন একটি a
(1 বাইট) প্রতিস্থাপনের সাথে ä
(2+ বাইট) আরও বেশি জায়গা তৈরি করতে হবে str
)। নির্দিষ্ট পদ্ধতি রয়েছে যা &str
স্থানে একটি পরিবর্তন করতে পারে , বেশিরভাগ সেগুলি কেবলমাত্র ASCII অক্ষর যেমন পরিচালনা করে make_ascii_uppercase
।
2 গতিশীল আকারের ধরণের জিনিসগুলি Rc<str>
মরিচা 1.2 এর পর থেকে ইউটিএফ -8 বাইট গণনা রেফারেন্সের ক্রমের জন্য পছন্দ করে । মরিচা 1.21 সহজেই এই ধরণের তৈরি করতে দেয়।
[u8; N]
।
Rc<str>
এবং Arc<str>
এখন স্ট্যান্ডার্ড লাইব্রেরির মাধ্যমে ব্যবহারযোগ্য।
আমার একটি সি ++ ব্যাকগ্রাউন্ড রয়েছে এবং আমি সি ++ পদগুলির সম্পর্কে String
এবং &str
এটি ভাবতে খুব দরকারী বলে মনে করি :
String
একটি মত std::string
; এটি মেমরির মালিক এবং মেমরি পরিচালনা করার নোংরা কাজ করে।&str
যেমন char*
কিছুটা পরিশীলিত); এটি একইভাবে একটি খণ্ডের শুরুতে আমাদেরকে নির্দেশ করে আপনি সামগ্রীর সামগ্রীতে একটি পয়েন্টার পেতে পারেন std::string
।তাদের মধ্যে কি অদৃশ্য হয়ে যাচ্ছে? আমি এমন মনে করি না. তারা দুটি উদ্দেশ্য পরিবেশন করে:
String
বাফার রাখে এবং ব্যবহার করা খুব ব্যবহারিক। &str
এটি হালকা ওজনের এবং স্ট্রিংগুলিতে "চেহারা" ব্যবহার করা উচিত। আপনি নতুন মেমরি বরাদ্দের প্রয়োজন ছাড়াই অনুসন্ধান করতে পারবেন, ভাগ করতে পারবেন, পার্স করতে পারবেন এবং এমনকি অংশগুলি প্রতিস্থাপন করতে পারেন।
&str
String
এটি কোনও স্ট্রিং আক্ষরিকের দিকে ইঙ্গিত করতে পারে তার ভিতরে দেখতে পারে। নিম্নলিখিত কোডটিতে আক্ষরিক স্ট্রিংটি String
পরিচালিত মেমোরিতে অনুলিপি করা দরকার :
let a: String = "hello rust".into();
নিম্নলিখিত কোডটি আপনাকে অনুলিপি ছাড়াই আক্ষরিক ব্যবহার করতে দেয় (কেবল পঠনযোগ্য)
let a: &str = "hello rust";
str
, কেবল হিসাবে ব্যবহৃত &str
, এটি একটি স্ট্রিং স্লাইস, কোনও ইউটিএফ -8 বাইট অ্যারের রেফারেন্স।
String
যা ব্যবহৃত ~str
হত, বর্ধনযোগ্য, মালিকানাধীন ইউটিএফ -8 বাইট অ্যারে।
~str
এখন যা ব্যবহৃত হত তা হলBox<str>
~str
বর্ধনযোগ্য ছিল এবং বর্ধনযোগ্য Box<str>
নয়। (এটি ~str
এবং ~[T]
যাদুকরভাবে বিকাশযোগ্য, অন্য কোনও উদ্দেশ্য থেকে ~
পৃথক, ঠিক কারণেই String
এবং Vec<T>
প্রবর্তন করা হয়েছিল, যাতে নিয়মগুলি সমস্ত সোজা এবং সামঞ্জস্যপূর্ণ ছিল))
এগুলি আসলে সম্পূর্ণ আলাদা। প্রথমত, 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
তার অর্থ অনেকগুলি অতিরিক্ত কোড লিখতে হবে যা এখন জেনেরিক হতে পারে।
&str
String
অনুলিপি ব্যতীত একাধিক বিভিন্ন সাবস্ট্রিং থাকতে সক্ষম হ'তে অতি দরকারী ; হিসাবে একটি বলল 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
সাব - স্ট্রিংগুলি হ'ল বাফারে কেবল ফ্যাট পয়েন্টার।
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 এ ছোট্ট পরিবর্তনটি তার বাইট দৈর্ঘ্য পরিবর্তন করতে পারে এবং একটি টুকরোটি তার পুনঃসমনকে পুনরায় স্থান দিতে পারে না।
সহজ কথায়, String
হিটে (ঠিক যেমন Vec
) ডেটাটাইপ সংরক্ষণ করা হয় এবং আপনার সেই অবস্থানটিতে অ্যাক্সেস থাকে।
&str
একটি স্লাইস টাইপ। এর অর্থ এটি হ'ল String
কোথাও কোথাও একটি ইতিমধ্যে উপস্থিত রেফারেন্স ।
&str
রানটাইমে কোনও বরাদ্দ না করে। সুতরাং, মেমরির কারণে, আপনি &str
ওভার ব্যবহার করতে পারেন String
। তবে, মনে রাখবেন যে ব্যবহার করার সময় &str
আপনাকে সুস্পষ্ট লাইফ টাইম মোকাবেলা করতে হতে পারে।
str
হ'ল view
ইতিমধ্যে উপস্থিত String
ap
সি # এবং জাভা লোকের জন্য:
String
===StringBuilder
&str
=== (অপরিবর্তনীয়) স্ট্রিংআমি &str
জাভা / সি # তে অভ্যন্তরীণ স্ট্রিংয়ের মতো একটি স্ট্রিংয়ের মতামত হিসাবে ভাবতে চাই যেখানে আপনি এটি পরিবর্তন করতে পারবেন না, কেবল একটি নতুন তৈরি করুন।
এখানে একটি দ্রুত এবং সহজ ব্যাখ্যা।
String
- একটি বর্ধনযোগ্য, মালিকানাযোগ্য হিপ-বরাদ্দ করা ডেটা কাঠামো। এটি একটি জোর করা যেতে পারে &str
।
str
- (এখন, মরিচা বিকশিত হওয়ার সাথে সাথে) পরিবর্তনযোগ্য, স্থির-দৈর্ঘ্যের স্ট্রিং যা গাদা বা বাইনারিগুলিতে থাকে। আপনি কেবল str
স্ট্রিং স্লাইস ভিউয়ের মাধ্যমে ধার করা ধরণের হিসাবে ইন্টারেক্ট করতে পারেন , যেমন &str
।
ব্যবহার বিবেচনা:
String
আপনি যদি স্ট্রিংটির মালিকানা বা রূপান্তর করতে চান তবে পছন্দ করুন - যেমন স্ট্রিংটিকে অন্য থ্রেডে পাস করা ইত্যাদি etc.
&str
আপনি যদি স্ট্রিংয়ের কেবল পঠনযোগ্য দর্শন পেতে চান তবে অগ্রাধিকার দিন ।
&str
দুই উপাদান গঠিত: কিছু বাইট একটি পয়েন্টার, এবং একটি দৈর্ঘ্য।"