পিএইচপি 7 ইন্টারফেস, রিটার্ন টাইপ ইঙ্গিত এবং স্ব


89

আপডেট : পিএইচপি 7.4 এখন সমবায়তা এবং বিপরীতে সমর্থন করে যা এই প্রশ্নটিতে উত্থাপিত প্রধান সমস্যাটিকে সম্বোধন করে।


আমি পিএইচপি ইঙ্গিত রিটার্ন টাইপ ব্যবহার করে একটি বিষয় কিছু পাতিত আছে 7. আমার বোঝার যে ইঙ্গিত হয় : selfমানে যে আপনি একটি বাস্তবায়নের বর্গ জন্য মনস্থ করা নিজেই দেখাবে। তাই আমি : selfএটি চিহ্নিত করতে আমার ইন্টারফেসগুলিতে ব্যবহার করেছি, তবে আমি যখন ইন্টারফেসটি বাস্তবায়নের চেষ্টা করেছি তখন আমি সামঞ্জস্যতার ত্রুটি পেয়েছি।

নীচে আমি যে ইস্যুটি চালিয়েছি তার একটি সহজ বোধ করা হল:

interface iFoo
{
    public function bar (string $baz) : self;
}

class Foo implements iFoo
{

    public function bar (string $baz) : self
    {
        echo $baz . PHP_EOL;
        return $this;
    }
}

(new Foo ()) -> bar ("Fred") 
    -> bar ("Wilma") 
    -> bar ("Barney") 
    -> bar ("Betty");

প্রত্যাশিত আউটপুটটি ছিল:

ফ্রেড উইলমা বার্নি বেটি

আমি আসলে যা পাই তা হ'ল:

পিএইচপি মারাত্মক ত্রুটি: ফুঃ এর ঘোষণা :: বার (ইন্টা-বাজ): ফু অবশ্যই আইএফও :: বার (ইনট-বাজ) এর সাথে সামঞ্জস্যপূর্ণ: আইফু line লাইনে টেস্ট.এফপি

জিনিসটি হ'ল ফু হ'ল আইফো-র একটি বাস্তবায়ন, তাই যতদূর আমি বলতে পারি প্রয়োগটি প্রদত্ত ইন্টারফেসের সাথে পুরোপুরি সামঞ্জস্যপূর্ণ হওয়া উচিত। আমি ইন্টারফেস বা প্রয়োগকারী শ্রেণি (অথবা উভয়) এর পরিবর্তে নাম বদলে ইন্টিফেসটি ব্যবহার না করে পরিবর্তনের মাধ্যমে এই সমস্যাটি সংশোধন করতে পারলাম self, তবে আমার বোঝার selfঅর্থ হল যে শব্দটির অর্থ "আপনি যে ক্লাসটি চালু করেছেন সেটির উদাহরণটি ফিরে আসুন " "। সুতরাং ইন্টারফেসে এটির পরিবর্তনের অর্থ তাত্ত্বিক অর্থ হ'ল আমি যখন এমন কোনও ঘটনার প্রত্যাবর্তন করতে পারলাম যা ইন্টারফেস প্রয়োগ করে তখন আমার উদ্দেশ্যটি হ'ল প্রত্যাবর্তিত দৃষ্টান্তটিই ফিরে আসবে।

এটি কি পিএইচপি-তে কোনও তদারকি বা এটি ইচ্ছাকৃতভাবে ডিজাইনের সিদ্ধান্ত? যদি এটি প্রাক্তন থাকে তবে এটি পিএইচপি 7.1-এ স্থির দেখার কোনও সম্ভাবনা আছে? যদি তা না হয় তবে ইঙ্গিত দেওয়ার সঠিক উপায়টি কী যা আপনার ইন্টারফেসটি প্রত্যাশা করে যে আপনি যে শৃঙ্খলার জন্য পদ্ধতিটি সবেমাত্র ডেকেছেন তা ফিরে আসবে?


আমি মনে করি পিএইচপি রিটার্ন টাইপ-হিন্টিং এ এটি একটি ত্রুটি, সম্ভবত আপনার এটি বাগ হিসাবে উত্থাপন করা উচিত ; তবে কোনও ফিক্স এই শেষ পর্যায়ে পিএইচপি 7.1 এ আসার সম্ভাবনা নেই
মার্ক বাকের

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

আগ্রহের বাইরে, আপনি কীভাবে selfরিটার্নের ধরণের কাজ করার কথা বলে তার ব্যাখ্যাটি পড়ছেন ?
অ্যাডাম ক্যামেরন

@ অ্যাডাম: "আপনারা যে উদাহরণটি বলেছেন সেটিকে ফিরিয়ে দিন self, একই ইন্টারফেসটি প্রয়োগকারী অন্য কোনও উদাহরণ নয়" বলে বোঝানো এটি যৌক্তিক বলে মনে হচ্ছে । আমার মনে হচ্ছে জাভাতেও একই রকমের রিটার্নের টাইপ ছিল (যদিও আমি কোনও জাভা প্রোগ্রামিং করে কিছুক্ষণ হয়ে গেছে)
GordonM

4
হাই গর্ডন ওয়েল এটি অন্য কোথাও কাজ করার নথিভুক্ত না হলে, আমি বাস্তবতা কি যৌক্তিক হতে পারে তা বিশ্বাস করি না। আমি যে পরিস্থিতিটি বর্ণনা করছি তার সাথে টিবিএইচ, আমি যথাসম্ভব ঘোষিত হতে পারব এবং রিটার্নের ধরণের মতো আইফু ব্যবহার করব। এমন কোনও পরিস্থিতি রয়েছে যা বাস্তবে কাজ করবে না? (আমি বুঝতে পেরেছি যে এটি "পরামর্শ" / মতামত "একটি উত্তর" নয়, যা বলেছিল
অ্যাডাম ক্যামেরন

উত্তর:


94

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

এটি বলেছিল যে পিএইচপি-তে রিটার্নের ধরণের ঘোষণাগুলি অবশ্যই অবিস্রষ্ট হওয়া উচিত যখন আপনি যা চেষ্টা করছেন সেগুলি সোভিয়েটারেন্ট।

আপনার ব্যবহার selfসমান:

interface iFoo
{
    public function bar (string $baz) : iFoo;
}

class Foo implements iFoo
{

    public function bar (string $baz) : Foo  {...}
}

যা অনুমোদিত নয়।


রিটার্ন টাইপ ঘোষণা বোঝায় যা RFC হয়েছে এই বলে :

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

...

এই আরএফসিটি মূলত কোভারিয়েন্ট রিটার্ন প্রকারের প্রস্তাব করেছিল তবে কয়েকটি সমস্যার কারণে এটি অবিস্রষ্ট্রে পরিবর্তিত হয়েছিল। ভবিষ্যতে কোনও সময়ে সমবায় রিটার্নের ধরণ যুক্ত করা সম্ভব।


আপাতত সবচেয়ে ভাল আপনি যা করতে পারেন তা হ'ল:

interface iFoo
{
    public function bar (string $baz) : iFoo;
}

class Foo implements iFoo
{

    public function bar (string $baz) : iFoo  {...}
}

19
এটি বলেছিল, আমি staticকাজ করার জন্য রিটার্নের টাইপ-ইঙ্গিতের প্রত্যাশা করতাম , তবে এটি
মার্ক বাকের

আমি বুঝতে পারি যে এটিই হবে এবং আমি এইভাবেই সমস্যাটি সমাধান করব। তবে আমি কেবল ব্যবহার করতে পছন্দ করতাম: সম্ভব হলে স্ব কারণ যদি কোনও শ্রেণি যদি কোনও ইন্টারফেস প্রয়োগ করে তবে স্ব-এর একটি ফেরতের মানও স্পষ্টত ইন্টারফেসের উদাহরণের একটি ফেরতের মান।
গর্ডনএম

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

এখানে আপনার উদ্ধৃতিটির একটি অংশের একটি গুরুত্বপূর্ণ উপস্থাপনা রয়েছে: " কোভেরিয়েন্ট রিটার্ন টাইপগুলি টাইপ শব্দ হিসাবে বিবেচিত হয় এবং অন্যান্য অনেক ভাষায় ব্যবহৃত হয় (সি ++ এবং জাভা কিন্তু সি # আমি বিশ্বাস করি না This) এই আরএফসি মূলত প্রস্তাবিত কোভেরিয়েন্ট রিটার্নের ধরণের তবে কয়েকটি সমস্যার কারণে অবিস্মরণীয় হয়ে গেছে " পিএইচপি-র কী সমস্যা ছিল তা আমি আগ্রহী। তাদের নকশার পছন্দটি বেশ কয়েকটি সীমাবদ্ধতার কারণ হয়ে দাঁড়ায় যা বৈশিষ্টগুলির সাথে অদ্ভুত সমস্যার কারণ হয়ে থাকে, যদি না আপনি রিটার্ন টাইপের বিধিনিষেধকে আলগা না করেন (নীচে কিছু জবাব হিসাবে দেখা যায়) তবে এগুলিকে অনেক ক্ষেত্রে কিছুটা অকেজো করে দেওয়া। খুবই হতাশাজনক.
জন প্যানকোস্ট

4
@ মারকবেকার staticপিএইচপি 8
রিকার্ডো বস

16

এটি একটি সমাধানও হতে পারে, যে আপনি কেবলমাত্র পিএইচপিডোকের মধ্যে ইন্টারফেসে স্পষ্টভাবে রিটার্নের ধরণটি সংজ্ঞায়িত করেন না এবং তারপরে আপনি বাস্তবায়নের ক্ষেত্রে নির্দিষ্ট রিটার্নের ধরণটি সংজ্ঞায়িত করতে পারেন:

interface iFoo
{
    public function bar (string $baz);
}

class Foo implements iFoo
{
    public function bar (string $baz) : Foo  {...}
}

4
বা Fooকেবল ব্যবহারের পরিবর্তে self
পরিবর্তে 20

2

যদি আপনি ইন্টারফেস থেকে জোর করতে চান, তবে সেই পদ্ধতিটি বস্তুটি ফিরে আসবে, তবে বস্তুর প্রকারটি ইন্টারফেসের ধরণ নয়, বরং শ্রেণি নিজেই হবে, তখন আপনি এটি এইভাবে লিখতে পারেন:

interface iFoo {
    public function bar (string $baz) : object;
}

class Foo implements iFoo {
    public function bar (string $baz) : self  {...}
}

এটি পিএইচপি 7.4 থেকে কাজ করছে।



0

এটি আমার কাছে প্রত্যাশিত আচরণের মতো দেখাচ্ছে।

পরিবর্তে Foo::barফিরে আসার জন্য আপনার পদ্ধতিটি পরিবর্তন করুন এবং এটি দিয়ে শেষ করুন।iFooself

ব্যাখ্যা:

selfইন্টারফেসে যেমন ব্যবহার করা হয় তার অর্থ "ধরণের একটি বস্তু iFoo"।
selfবাস্তবায়নে যেমন ব্যবহার করা হয় তার অর্থ "ধরণের একটি বস্তু Foo"।

সুতরাং, ইন্টারফেস এবং বাস্তবায়নের ক্ষেত্রে রিটার্নের ধরণগুলি স্পষ্টভাবে এক নয়।

মন্তব্যের একটিতে জাভা এবং আপনার এই সমস্যাটি থাকবে কিনা তা উল্লেখ করা হয়েছে। উত্তর হ্যাঁ, জাভা আপনাকে এমন কোড লেখার অনুমতি দিলে আপনার একই সমস্যা হবে - যা এটি নয়। যেহেতু জাভাতে আপনাকে পিএইচপি-র selfশর্টকাটের পরিবর্তে টাইপের নামটি ব্যবহার করা প্রয়োজন , আপনি কখনই বাস্তবে এটি দেখতে যাবেন না। ( জাভাতে অনুরূপ ইস্যুটির আলোচনার জন্য এখানে দেখুন ))


তাহলে কি ঘোষনা দেওয়ার selfমতোই ঘোষনা করা হচ্ছে MyClass::class?
পিটারচাউলা

4
@ লেজার হ্যাঁ, এটি।
মোশে কাটজ

4
তবে যদি ফু আইফু প্রয়োগ করে তবে ফু আইফু টাইপের সংজ্ঞা অনুসারে
GordonM
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.