সংকলকটি আমাকে গাইড করতে কার্যকরভাবে খুঁজে পেয়েছি:
fn to_words(text: &str) { // Note no return type
text.split(' ')
}
সংকলন দেয়:
error[E0308]: mismatched types
--> src/lib.rs:5:5
|
5 | text.split(' ')
| ^^^^^^^^^^^^^^^ expected (), found struct `std::str::Split`
|
= note: expected type `()`
found type `std::str::Split<'_, char>`
help: try adding a semicolon
|
5 | text.split(' ');
| ^
help: try adding a return type
|
3 | fn to_words(text: &str) -> std::str::Split<'_, char> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
সংকলকের পরামর্শ এবং অনুলিপি অনুসরণ করে যে আমার রিটার্ন টাইপ হিসাবে (একটু পরিষ্কারের সাথে):
use std::str;
fn to_words(text: &str) -> str::Split<'_, char> {
text.split(' ')
}
সমস্যাটি হ'ল আপনি এমন বৈশিষ্ট্যটি ফিরিয়ে দিতে পারবেন না Iterator
কারণ একটি বৈশিষ্ট্যের আকার থাকে না। এর অর্থ রাস্টটি জানেন না যে প্রকারের জন্য কত স্থান বরাদ্দ করতে হবে। আপনি স্থানীয় ভেরিয়েবলের কোনও রেফারেন্স ফিরিয়ে দিতে পারবেন না , সুতরাং প্রত্যাবর্তন &dyn Iterator
হ'ল স্টার্টার।
ইমপ্লিট বৈশিষ্ট্য
মরিচা 1.26 হিসাবে, আপনি ব্যবহার করতে পারেন impl trait
:
fn to_words<'a>(text: &'a str) -> impl Iterator<Item = &'a str> {
text.split(' ')
}
fn main() {
let text = "word1 word2 word3";
println!("{}", to_words(text).take(2).count());
}
এটি কীভাবে ব্যবহার করা যায় তার উপর বিধিনিষেধ রয়েছে। আপনি কেবল একটি একক প্রকার (কোনও শর্তসাপেক্ষ!) ফেরত দিতে পারেন এবং এটি অবশ্যই একটি ফাংশন বা সহজাত প্রয়োগের জন্য ব্যবহার করা উচিত।
boxed
আপনি যদি কিছুটা দক্ষতা হারাতে আপত্তি না করেন তবে আপনি ফিরে আসতে পারেন Box<dyn Iterator>
:
fn to_words<'a>(text: &'a str) -> Box<dyn Iterator<Item = &'a str> + 'a> {
Box::new(text.split(' '))
}
fn main() {
let text = "word1 word2 word3";
println!("{}", to_words(text).take(2).count());
}
এটি প্রাথমিক বিকল্প যা গতিশীল প্রেরণের অনুমতি দেয় । অর্থাৎ কোডটির সঠিক প্রয়োগটি সংকলন-সময়ের পরিবর্তে রান-টাইমে সিদ্ধান্ত নেওয়া হয়। এর অর্থ এটি এমন ক্ষেত্রে উপযুক্ত যেখানে আপনার শর্তের ভিত্তিতে একাধিক কংক্রিট ধরণের পুনরাবৃত্তি করতে হবে।
নতুন ধরনের
use std::str;
struct Wrapper<'a>(str::Split<'a, char>);
impl<'a> Iterator for Wrapper<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<&'a str> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
fn to_words(text: &str) -> Wrapper<'_> {
Wrapper(text.split(' '))
}
fn main() {
let text = "word1 word2 word3";
println!("{}", to_words(text).take(2).count());
}
উপনাম টাইপ করুন
রিম দ্বারা নির্দেশিত হিসাবে
use std::str;
type MyIter<'a> = str::Split<'a, char>;
fn to_words(text: &str) -> MyIter<'_> {
text.split(' ')
}
fn main() {
let text = "word1 word2 word3";
println!("{}", to_words(text).take(2).count());
}
ক্লোজারগুলির সাথে ডিল করছে
যখন impl Trait
ব্যবহারের জন্য উপলব্ধ না হয়, বন্ধগুলি জিনিসগুলিকে আরও জটিল করে তোলে। বন্ধগুলি বেনামে প্রকার তৈরি করে এবং এগুলি ফেরতের প্রকারে নাম দেওয়া যায় না:
fn odd_numbers() -> () {
(0..100).filter(|&v| v % 2 != 0)
}
found type `std::iter::Filter<std::ops::Range<{integer}>, [closure@src/lib.rs:4:21: 4:36]>`
কিছু ক্ষেত্রে, এই ক্লোজারগুলি ফাংশনগুলির সাথে প্রতিস্থাপন করা যেতে পারে, যার নাম দেওয়া যেতে পারে:
fn odd_numbers() -> () {
fn f(&v: &i32) -> bool {
v % 2 != 0
}
(0..100).filter(f as fn(v: &i32) -> bool)
}
found type `std::iter::Filter<std::ops::Range<i32>, for<'r> fn(&'r i32) -> bool>`
এবং উপরোক্ত পরামর্শ অনুসরণ:
use std::{iter::Filter, ops::Range};
type Odds = Filter<Range<i32>, fn(&i32) -> bool>;
fn odd_numbers() -> Odds {
fn f(&v: &i32) -> bool {
v % 2 != 0
}
(0..100).filter(f as fn(v: &i32) -> bool)
}
শর্তসাপেক্ষে কাজ করা
যদি আপনাকে শর্তসাপেক্ষে একটি পুনরুক্তি প্রদানকারী চয়ন করতে হয় তবে শর্তাধীন বেশ কয়েকটি সম্ভাব্য পুনরুক্তির মধ্যে একটির উপর শর্তসাপেক্ষে পুনরাবৃত্তি পড়ুন ।