মরিচের সঠিক অটো-ডিফারেন্সিং বিধিগুলি কী কী?


180

আমি মরিচাটির সাথে শিখছি / পরীক্ষা নিরীক্ষা করছি এবং এই ভাষায় আমি যে কমনীয়তা পেয়েছি সেখানে একটি বিশেষত্ব আছে যা আমাকে বিস্মিত করে এবং পুরোপুরি জায়গা থেকে দূরে বলে মনে হয়।

মেথড কল করার সময় মরিচা স্বয়ংক্রিয়ভাবে পয়েন্টারগুলিকে ডিফেরেন্ট করে। সঠিক আচরণ নির্ধারণের জন্য আমি কিছু পরীক্ষা করেছি:

struct X { val: i32 }
impl std::ops::Deref for X {
    type Target = i32;
    fn deref(&self) -> &i32 { &self.val }
}

trait M { fn m(self); }
impl M for i32   { fn m(self) { println!("i32::m()");  } }
impl M for X     { fn m(self) { println!("X::m()");    } }
impl M for &X    { fn m(self) { println!("&X::m()");   } }
impl M for &&X   { fn m(self) { println!("&&X::m()");  } }
impl M for &&&X  { fn m(self) { println!("&&&X::m()"); } }

trait RefM { fn refm(&self); }
impl RefM for i32  { fn refm(&self) { println!("i32::refm()");  } }
impl RefM for X    { fn refm(&self) { println!("X::refm()");    } }
impl RefM for &X   { fn refm(&self) { println!("&X::refm()");   } }
impl RefM for &&X  { fn refm(&self) { println!("&&X::refm()");  } }
impl RefM for &&&X { fn refm(&self) { println!("&&&X::refm()"); } }


struct Y { val: i32 }
impl std::ops::Deref for Y {
    type Target = i32;
    fn deref(&self) -> &i32 { &self.val }
}

struct Z { val: Y }
impl std::ops::Deref for Z {
    type Target = Y;
    fn deref(&self) -> &Y { &self.val }
}


#[derive(Clone, Copy)]
struct A;

impl M for    A { fn m(self) { println!("A::m()");    } }
impl M for &&&A { fn m(self) { println!("&&&A::m()"); } }

impl RefM for    A { fn refm(&self) { println!("A::refm()");    } }
impl RefM for &&&A { fn refm(&self) { println!("&&&A::refm()"); } }


fn main() {
    // I'll use @ to denote left side of the dot operator
    (*X{val:42}).m();        // i32::m()    , Self == @
    X{val:42}.m();           // X::m()      , Self == @
    (&X{val:42}).m();        // &X::m()     , Self == @
    (&&X{val:42}).m();       // &&X::m()    , Self == @
    (&&&X{val:42}).m();      // &&&X:m()    , Self == @
    (&&&&X{val:42}).m();     // &&&X::m()   , Self == *@
    (&&&&&X{val:42}).m();    // &&&X::m()   , Self == **@
    println!("-------------------------");

    (*X{val:42}).refm();     // i32::refm() , Self == @
    X{val:42}.refm();        // X::refm()   , Self == @
    (&X{val:42}).refm();     // X::refm()   , Self == *@
    (&&X{val:42}).refm();    // &X::refm()  , Self == *@
    (&&&X{val:42}).refm();   // &&X::refm() , Self == *@
    (&&&&X{val:42}).refm();  // &&&X::refm(), Self == *@
    (&&&&&X{val:42}).refm(); // &&&X::refm(), Self == **@
    println!("-------------------------");

    Y{val:42}.refm();        // i32::refm() , Self == *@
    Z{val:Y{val:42}}.refm(); // i32::refm() , Self == **@
    println!("-------------------------");

    A.m();                   // A::m()      , Self == @
    // without the Copy trait, (&A).m() would be a compilation error:
    // cannot move out of borrowed content
    (&A).m();                // A::m()      , Self == *@
    (&&A).m();               // &&&A::m()   , Self == &@
    (&&&A).m();              // &&&A::m()   , Self == @
    A.refm();                // A::refm()   , Self == @
    (&A).refm();             // A::refm()   , Self == *@
    (&&A).refm();            // A::refm()   , Self == **@
    (&&&A).refm();           // &&&A::refm(), Self == @
}

( খেলার মাঠ )

সুতরাং, এটি কম-বেশি:

  • সংকলকটি কোনও পদ্ধতিতে ডাকতে প্রয়োজনীয় হিসাবে অনেক ডিরিফারেন্স অপারেটর সন্নিবেশ করবে।
  • সংকলক, যখন সমাধানগুলির পদ্ধতিগুলি &self(কল-বাই-রেফারেন্স) ব্যবহার করে ঘোষণা করা হয়েছিল:
    • প্রথমে এর একক সম্মানের জন্য আহ্বান জানাতে চেষ্টা করুন self
    • তারপরে সঠিক ধরণের জন্য ফোন করার চেষ্টা করে self
    • তারপরে, কোনও ম্যাচের জন্য প্রয়োজনীয় যতগুলি ডিরিফারেন্স অপারেটর inোকানোর চেষ্টা করে
  • selfপ্রকারের জন্য (কল-বাই-মান) ব্যবহার করে ঘোষিত পদ্ধতিগুলি Tএমনভাবে আচরণ করে যেন এগুলি টাইপের জন্য &self(কল-বাই-রেফারেন্স) ব্যবহার করে ঘোষিত হয়েছিল &Tএবং বিন্দু অপারেটরের বাম দিকে যা আছে তার রেফারেন্সটিতে কল করা হয়েছে।
  • উপরোক্ত নিয়মগুলি প্রথমে কাঁচা বিল্ট-ইন ডেরেফারেন্স দিয়ে চেষ্টা করা হয় এবং যদি কোনও মিল না থাকে তবে Derefবৈশিষ্ট্যযুক্ত ওভারলোড ব্যবহার করা হয়।

সঠিক স্বতঃ-নির্ধারণের বিধিগুলি কী কী? এমন ডিজাইনের সিদ্ধান্তের জন্য কেউ কি কোনও আনুষ্ঠানিক যুক্তি দিতে পারেন?


কিছু ভাল উত্তর পাওয়ার আশায় আমি এটিকে জাস্ট সাবড্রেডিতে ক্রস পোস্ট করেছি !
শেপমাস্টার

অতিরিক্ত মজাদার জন্য জেনেরিকগুলিতে পরীক্ষার পুনরাবৃত্তি করার চেষ্টা করুন এবং ফলাফলগুলি তুলনা করুন।
ব্যবহারকারী 2665887

উত্তর:


137

আপনার সিউডো কোডটি বেশ সঠিক। এই উদাহরণস্বরূপ, ধরুন আমাদের একটি পদ্ধতি কল ছিল foo.bar()যেখানে foo: T। আমি ব্যবহার করতে যাচ্ছি সম্পূর্ণরূপে যোগ্যতাসম্পন্ন সিনট্যাক্স (FQS) যা টাইপ পদ্ধতি সঙ্গে বলা হচ্ছে, যেমন সম্পর্কে দ্ব্যর্থহীন হতে A::bar(foo)বা A::bar(&***foo)। আমি কেবল এলোমেলো মূলধন অক্ষরের একটি গাদা লিখতে চলেছি, প্রত্যেকে কেবলমাত্র কিছু স্বেচ্ছাসেবী প্রকার / বৈশিষ্ট্যযুক্ত, ব্যতীত Tসর্বদা মূল চলকটির ধরণ fooযা পদ্ধতিতে ডাকা হয়।

অ্যালগরিদমের মূলটি হ'ল:

  • প্রতিটি "বিন্যাস পদক্ষেপ" U (যা, সেট U = Tএবং তারপরে U = *T...)
    1. যদি এমন কোনও পদ্ধতি থাকে barযেখানে রিসিভারের ধরণটি ( selfপদ্ধতিতে প্রকারের ) Uঠিক মিলে যায় তবে এটি ব্যবহার করুন ( একটি "মান পদ্ধতির দ্বারা" )
    2. অন্যথায়, একটি অটো-রেফ যুক্ত করুন (গ্রহণ করুন &বা &mutগ্রহণকারীর) এবং, যদি কোনও পদ্ধতির রিসিভারের সাথে মেলে &U, এটি ব্যবহার করুন ( একটি "অটোরিফিড পদ্ধতি" )

উল্লেখ্য, সবকিছু পদ্ধতির "রিসিভার টাইপ", বিবেচনা করে নাSelf বৈশিষ্ট্যের ধরন, অর্থাত impl ... for Foo { fn method(&self) {} }নিয়ে চিন্তা করে &Fooযখন পদ্ধতি মিলে, এবং fn method2(&mut self)সম্পর্কে মনে হবে &mut Fooযখন মিল।

অভ্যন্তরীণ পদক্ষেপগুলিতে বৈধতাযুক্ত একাধিক বৈশিষ্ট্য যদি সেখানে থাকে তবে এটি ত্রুটিযুক্ত (এটি কেবলমাত্র শূন্য হতে পারে বা প্রতিটি বৈশিষ্ট্য 1 বা ২ এর মধ্যে বৈধ হতে পারে তবে প্রতিটিটির জন্য একটি বৈধ থাকতে পারে: একটি 1 থেকে প্রথমে নেওয়া হবে) এবং অন্তর্নিহিত পদ্ধতিগুলি বৈশিষ্ট্যের চেয়ে বেশি অগ্রাধিকার গ্রহণ করে। এটি মিলে যায় এমন কোনও কিছুই না পেয়ে আমরা লুপের শেষে পৌঁছে দিলে এটিও একটি ত্রুটি। পুনরাবৃত্তিমূলক Derefবাস্তবায়ন হওয়াও ত্রুটি , যা লুপকে অসীম করে তোলে (তারা "পুনরাবৃত্তির সীমাতে" আঘাত করবে)।

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

শুধুমাত্র একটি স্ব-রেফারেন্স যুক্ত করা হয়েছে কারণ

  • যদি কোনও সীমাবদ্ধ না থাকে তবে জিনিসগুলি খারাপ / ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে পড়তে পারে যেহেতু প্রতিটি ধরণের একটি স্বেচ্ছাসেবী রেফারেন্স নেওয়া যেতে পারে
  • একটি রেফারেন্স নেওয়া তার &fooসাথে দৃ strong় সংযোগ বজায় রাখে foo(এটি fooনিজের ঠিকানা ) তবে এটি হারাতে আরও শুরু করা: &&fooস্ট্যাকের স্ট্যাকের কিছু অস্থায়ী পরিবর্তনশীলের ঠিকানা &foo

উদাহরণ

ধরুন আমাদের কল রয়েছে foo.refm(), যদি fooটাইপ থাকে:

  • X, তারপরে আমরা শুরু করি U = X, refmরিসিভারের ধরণ রয়েছে &..., সুতরাং পদক্ষেপ 1 মেলে না, একটি অটো-রেফার নেওয়া আমাদের দেয় &X, এবং এটি মেলে (এর সাথে Self = X), সুতরাং কলটিRefM::refm(&foo)
  • &X, দিয়ে শুরু হয় U = &X, যা &selfপ্রথম ধাপে মেলে (এর সাথে Self = X), এবং তাই কলRefM::refm(foo)
  • &&&&&X, এটি কোনও পদক্ষেপের সাথে মেলে না (বৈশিষ্টটি এর জন্য প্রয়োগ করা হয়নি &&&&Xবা &&&&&X), তাই আমরা একবারে খুঁজে পেতে সম্মান করি U = &&&&X, যা 1 (সহ Self = &&&X) এর সাথে মেলে এবং কলটি হলRefM::refm(*foo)
  • Z, হয় ধাপ তাই এটি পেতে একবার dereferenced হয়, সাথে মেলে না Y, যা মেলে না, তাই এটি পেতে আবার dereferenced এর X, যা 1 মিলছে না, কিন্তু autorefing পর ম্যাচ করে, যাতে কল RefM::refm(&**foo)
  • &&A, 1. টি মেলে না এবং 2ও হয় না 2 যেহেতু বৈশিষ্ট্যটি &A(1 এর জন্য) বা &&A(2) এর জন্য প্রয়োগ করা হয়নি , সুতরাং এটি 1 টির সাথে &Aমিলিত, যা 1 এর সাথে মেলেSelf = A

ধরুন আমরা আছে foo.m(), এবং যে Aনয় Copy, যদি fooপ্রকার আছে:

  • Aতারপর, U = Aসাথে মেলে selfসরাসরি তাই কল M::m(foo)সঙ্গেSelf = A
  • &Aএরপরে, 1 টি মেলে না এবং 2ও হয় না ( বৈশিষ্ট্যটিও কার্যকর করা যায় না &Aএবং &&Aপ্রয়োগও করা হয় না), সুতরাং এটির সাথে সম্মানিত হয় Aযা মিলছে না, তবে মান M::m(*foo)অনুসারে গ্রহণ Aকরা প্রয়োজন এবং তাই এর বাইরে চলে যাওয়া foo, ত্রুটি।
  • &&A, 1. সাথে মেলে না, কিন্তু autorefing দেয় &&&A, যা ম্যাচ, তাই কল M::m(&foo)সঙ্গে Self = &&&A

(এই উত্তরটি কোডের উপর ভিত্তি করে তৈরি হয়েছে , এবং যুক্তিসঙ্গতভাবে (সামান্য পুরানো) পুনঃনির্মাণের নিকটবর্তী। সংকলক / ভাষার এই অংশটির মূল লেখক নিকো মাতসাকিসও এই উত্তরের দিকে নজর দিয়েছেন।)


15
এই উত্তরটি সম্পূর্ণরূপে এবং বিশদযুক্ত বলে মনে হচ্ছে তবে আমি মনে করি এটিতে বিধিগুলির একটি সংক্ষিপ্ত এবং অ্যাক্সেসযোগ্য সংক্ষেপের অভাব রয়েছে। শেপমাস্টারের এই মন্তব্যে এই জাতীয় একটি সংক্ষিপ্তসার দেওয়া হয়েছে : "এটি [দেরেফ অ্যালগরিদম] যতবার সম্ভব ( &&String-> &String-> String-> str) দ্বিগুণ হবে এবং তারপরে সর্বোচ্চ একবারে ( str-> &str) রেফারেন্স "।
Lii

(এই ব্যাখ্যাটি আমার নিজের পক্ষে কতটা সঠিক এবং সম্পূর্ণ তা আমি জানি না))
লিই

1
কোন ক্ষেত্রে অটো ডেরেফারিং হয়? এটি কি পদ্ধতি কলের জন্য কেবল গ্রহনকারী অভিব্যক্তির জন্য ব্যবহৃত হয়? ক্ষেত্রের প্রবেশের জন্যও? ডানহাতি পক্ষের বরাদ্দ? বাম দিকে? ফাংশন পরামিতি? ফেরত মান প্রকাশ?
Lii

1
দ্রষ্টব্য: বর্তমানে, এই উত্তরটি থেকে তথ্য চুরি করতে এবং স্ট্যাটিক.রোস্ট-lang.org/doc/master/nomicon/dot-operator.html
স্যামবি

1
জোর করে (এ) এর আগে চেষ্টা করা হয়েছিল বা (খ) এর পরে চেষ্টা করা হয়েছে বা (সি) এই অ্যালগরিদমের প্রতিটি পদক্ষেপে চেষ্টা করেছে বা (ডি) অন্য কিছু?
haslersn

8

মরিচা রেফারেন্সে মেথড কল এক্সপ্রেশন সম্পর্কে একটি অধ্যায় রয়েছে । আমি নীচের সবচেয়ে গুরুত্বপূর্ণ অংশটি অনুলিপি করেছি। অনুস্মারক: আমরা একটি অভিব্যক্তি সম্পর্কে কথা বলছি recv.m(), যেখানে recvনীচে "রিসিভার এক্সপ্রেশন" বলা হয়।

প্রথম পদক্ষেপটি প্রার্থীদের রিসিভার ধরণের তালিকা তৈরি করা। রিসিভার এক্সপ্রেশনের ধরণের বার বার ডিফারেন্স করে এগুলি পান, তালিকায় প্রতিটি ধরণের মুখোমুখি যোগ করে, শেষে অবশেষে একটি অচলিত জবরদস্তির চেষ্টা করে এবং যদি সফল হয় তবে ফলাফলের ধরণ যুক্ত করে। এর পরে, প্রতিটি প্রার্থী T, অ্যাড &Tএবং &mut Tঅবিলম্বে পরে লিস্টে T

উদাহরণস্বরূপ, যদি আপনার রিসিভার টাইপ হয়েছে Box<[i32;2]>, তারপর প্রার্থী ধরনের হতে হবে Box<[i32;2]>, &Box<[i32;2]>, &mut Box<[i32;2]>, [i32; 2](dereferencing দ্বারা), &[i32; 2], &mut [i32; 2], [i32](unsized বলপ্রয়োগ দ্বারা), &[i32], এবং পরিশেষে &mut [i32]

তারপরে, প্রতিটি প্রার্থীর প্রকারের জন্য T, নিম্নলিখিত স্থানে সেই ধরণের রিসিভারের সাথে একটি দৃশ্যমান পদ্ধতির সন্ধান করুন:

  1. Tএর অন্তর্নিহিত পদ্ধতি (পদ্ধতিগুলি T[¹] এ সরাসরি প্রয়োগ করা হয় )।
  2. দ্বারা দৃশ্যমান বৈশিষ্ট্য দ্বারা প্রদত্ত যে কোনও পদ্ধতির দ্বারা প্রয়োগ করা হয় T। [...]

( [¹] সম্পর্কে দ্রষ্টব্য:) আমি আসলে এই শব্দবন্ধটি ভুল বলে মনে করি I've আমি একটি সমস্যা খুলেছি Let's আসুন আমরা এই বাক্যটিকে প্রথম বন্ধনীতে উপেক্ষা করি)


আসুন আপনার কোড থেকে কয়েকটি উদাহরণে বিশদভাবে চলুন! আপনার উদাহরণগুলির জন্য, আমরা "আনসাইজড জবরদস্তি" এবং "সহজাত পদ্ধতিগুলি" সম্পর্কে অংশটিকে উপেক্ষা করতে পারি।

(*X{val:42}).m(): রিসিভার এক্সপ্রেশন এর ধরণ i32। আমরা এই পদক্ষেপগুলি সম্পাদন করি:

  • প্রার্থী গ্রহণের ধরণের তালিকা তৈরি করা:
    • i32 উপস্থাপন করা যায় না, তাই আমরা ইতিমধ্যে 1 ধাপে সম্পন্ন করেছি List তালিকা: [i32]
    • পরবর্তী, আমরা যোগ &i32এবং &mut i32। তালিকা:[i32, &i32, &mut i32]
  • প্রতিটি প্রার্থী রিসিভার প্রকারের জন্য পদ্ধতিগুলি সন্ধান করছে:
    • আমরা <i32 as M>::mপাই যা রিসিভার টাইপ আছে i32। সুতরাং আমরা ইতিমধ্যে সম্পন্ন হয়েছে।


এখন পর্যন্ত এত সহজ। এখন একটি আরো কঠিন উদাহরণ বাছাই যাক: (&&A).m()। রিসিভার এক্সপ্রেশন এর ধরণ &&A। আমরা এই পদক্ষেপগুলি সম্পাদন করি:

  • প্রার্থী গ্রহণের ধরণের তালিকা তৈরি করা:
    • &&Aএর সাথে সমাহার করা যায় &A, তাই আমরা এটিকে তালিকায় যুক্ত করি। &Aআবার dereferences করা যেতে পারে, তাই আমরা Aতালিকাতে যুক্ত। Aঅবজ্ঞা করা যায় না, তাই আমরা থামি stop তালিকা:[&&A, &A, A]
    • এরপরে, Tতালিকার প্রতিটি ধরণের জন্য , আমরা যুক্ত করি &Tএবং &mut Tততক্ষণে T। তালিকা:[&&A, &&&A, &mut &&A, &A, &&A, &mut &A, A, &A, &mut A]
  • প্রতিটি প্রার্থী রিসিভার প্রকারের জন্য পদ্ধতিগুলি সন্ধান করছে:
    • রিসিভার টাইপ সহ কোনও পদ্ধতি নেই &&A, তাই আমরা তালিকার পরবর্তী ধরণে যাই।
    • আমরা <&&&A as M>::mপ্রকৃতপক্ষে রিসিভারের ধরণ রয়েছে এমন পদ্ধতিটি আবিষ্কার করি &&&A। সুতরাং আমরা সম্পন্ন।

আপনার সমস্ত উদাহরণের জন্য এখানে প্রার্থী গ্রহণের তালিকা রয়েছে। যে ধরণের সংযুক্তি রয়েছে ⟪x⟫তা হ'ল "জিতেছে", অর্থাত্ প্রথম প্রকারের জন্য যা কোনও মানানসই পদ্ধতিটি খুঁজে পেতে পারে। এছাড়াও মনে রাখবেন যে তালিকার প্রথম ধরণটি সর্বদা গ্রহনকারী এক্সপ্রেশনের ধরণ। শেষ অবধি, আমি তিনটি লাইনে তালিকাটি ফর্ম্যাট করেছিলাম, তবে এটি কেবল ফর্ম্যাট করে: এই তালিকাটি একটি সমতল তালিকা।

  • (*X{val:42}).m()<i32 as M>::m
    [i32, &i32, &mut i32]
  • X{val:42}.m()<X as M>::m
    [⟪X⟫, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&X{val:42}).m()<&X as M>::m
    [&X⟫, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&X{val:42}).m()<&&X as M>::m
    [&&X⟫, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&&X{val:42}).m()<&&&X as M>::m
    [&&&X⟫, &&&&X, &mut &&&X, 
     &&X, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&&&X{val:42}).m()<&&&X as M>::m
    [&&&&X, &&&&&X, &mut &&&&X,&&&X⟫, &&&&X, &mut &&&X, 
     &&X, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&&&&X{val:42}).m()<&&&X as M>::m
    [&&&&&X, &&&&&&X, &mut &&&&&X, 
     &&&&X, &&&&&X, &mut &&&&X,&&&X⟫, &&&&X, &mut &&&X, 
     &&X, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]


  • (*X{val:42}).refm()<i32 as RefM>::refm
    [i32,&i32, &mut i32]
  • X{val:42}.refm()<X as RefM>::refm
    [X,&X⟫, &mut X, 
     i32, &i32, &mut i32]
  • (&X{val:42}).refm()<X as RefM>::refm
    [&X⟫, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&X{val:42}).refm()<&X as RefM>::refm
    [&&X⟫, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&&X{val:42}).refm()<&&X as RefM>::refm
    [&&&X⟫, &&&&X, &mut &&&X, 
     &&X, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&&&X{val:42}).refm()<&&&X as RefM>::refm
    [&&&&X⟫, &&&&&X, &mut &&&&X, 
     &&&X, &&&&X, &mut &&&X, 
     &&X, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]
  • (&&&&&X{val:42}).refm()<&&&X as RefM>::refm
    [&&&&&X, &&&&&&X, &mut &&&&&X,&&&&X⟫, &&&&&X, &mut &&&&X, 
     &&&X, &&&&X, &mut &&&X, 
     &&X, &&&X, &mut &&X, 
     &X, &&X, &mut &X, 
     X, &X, &mut X, 
     i32, &i32, &mut i32]


  • Y{val:42}.refm()<i32 as RefM>::refm
    [Y, &Y, &mut Y,
     i32,&i32, &mut i32]
  • Z{val:Y{val:42}}.refm()<i32 as RefM>::refm
    [Z, &Z, &mut Z,
     Y, &Y, &mut Y,
     i32,&i32, &mut i32]


  • A.m()<A as M>::m
    [⟪A⟫, &A, &mut A]
  • (&A).m()<A as M>::m
    [&A, &&A, &mut &A,
     ⟪A⟫, &A, &mut A]
  • (&&A).m()<&&&A as M>::m
    [&&A,&&&A⟫, &mut &&A,
     &A, &&A, &mut &A,
     A, &A, &mut A]
  • (&&&A).m()<&&&A as M>::m
    [&&&A⟫, &&&&A, &mut &&&A,
     &&A, &&&A, &mut &&A,
     &A, &&A, &mut &A,
     A, &A, &mut A]
  • A.refm()<A as RefM>::refm
    [A,&A⟫, &mut A]
  • (&A).refm()<A as RefM>::refm
    [&A⟫, &&A, &mut &A,
     A, &A, &mut A]
  • (&&A).refm()<A as RefM>::refm
    [&&A, &&&A, &mut &&A,&A⟫, &&A, &mut &A,
     A, &A, &mut A]
  • (&&&A).refm()<&&&A as RefM>::refm
    [&&&A,&&&&A⟫, &mut &&&A,
     &&A, &&&A, &mut &&A,
     &A, &&A, &mut &A,
     A, &A, &mut A]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.