একটি ফাংশন শুধুমাত্র একটি রিটার্ন বিবৃতি থাকা উচিত?


780

কোনও কার্যক্রমে কেবলমাত্র একটি রিটার্নের বিবৃতি দেওয়া ভাল অভ্যাসের ভাল কারণ রয়েছে?

অথবা কোনও কাজ থেকে এটি যুক্তিযুক্তভাবে সঠিক হওয়ার সাথে সাথেই ফিরে আসা ঠিক আছে, মানে ফাংশনে অনেকগুলি রিটার্নের বিবৃতি থাকতে পারে?


25
আমি একমত নই যে প্রশ্নটি ভাষা অজ্ঞাত। কিছু ভাষার সাথে একাধিক রিটার্ন পাওয়া অন্যের চেয়ে প্রাকৃতিক এবং সুবিধাজনক। আমি আরআইআই ব্যবহার করে এমন একটি সি ++ এর চেয়ে সি ফাংশনে প্রাথমিক রিটার্ন সম্পর্কে অভিযোগ করার বেশি সম্ভাবনা পাব।
অ্যাড্রিয়ান ম্যাকার্থি

3
এটি নিবিড়ভাবে সম্পর্কিত এবং এর চমৎকার উত্তর রয়েছে: প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জার
প্রশ্নস / ১১৮70০৩/২

ভাষা-অজ্ঞেয়বাদী? ফাংশনাল ভাষা ব্যবহার করে এমন কাউকে ব্যাখ্যা করুন যে তাকে অবশ্যই ফাংশন অনুযায়ী একটি রিটার্ন ব্যবহার করতে হবে: পি
বোইথিয়াস

উত্তর:


741

"সহজ" পরিস্থিতিতে ফিরে আসার পদ্ধতিটির শুরুতে আমার প্রায়শই বেশ কয়েকটি বিবৃতি থাকে। উদাহরণস্বরূপ, এটি:

public void DoStuff(Foo foo)
{
    if (foo != null)
    {
        ...
    }
}

... এর মতো আরও পাঠযোগ্য (আইএমএইচও) তৈরি করা যায়:

public void DoStuff(Foo foo)
{
    if (foo == null) return;

    ...
}

সুতরাং হ্যাঁ, আমি মনে করি কোনও ফাংশন / পদ্ধতি থেকে একাধিক "প্রস্থানস্থান" রাখা ভাল।


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

172
এটি "গার্ড স্টেটমেন্ট" হিসাবে পরিচিত এটি ফোলারের রিফ্যাক্টরিং।
লার্স ওয়েস্টারগ্রেন

12
ফাংশনগুলি তুলনামূলকভাবে সংক্ষিপ্ত রাখা হয়, মাঝখানে কাছাকাছি একটি রিটার্ন পয়েন্ট সঙ্গে একটি ফাংশন এর কাঠামো অনুসরণ করা কঠিন নয়।
কেজেএওয়াল্ফ

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

7
'কল্পনা করুন:' ডস স্টাফ 'ফাংশন শেষে আপনার "ইনসিভেস স্টাফক্যালকাউন্টার" পদ্ধতিটি করা দরকার। এক্ষেত্রে আপনি কী করবেন? :) '-DoStuff() { DoStuffInner(); IncreaseStuffCallCounter(); }
জিম বাল্টার

355

কেউই কোড কমপ্লিটের উল্লেখ বা উদ্ধৃত করেনি তাই আমি এটি করব।

17.1 রিটার্ন

প্রতিটি রুটিনে রিটার্নের সংখ্যা হ্রাস করুন । কোনও রুটিনটি বোঝা আরও শক্ত যদি এটি নীচে পড়ে, আপনি কোথাও উপরে ফিরে আসার সম্ভাবনা সম্পর্কে অবগত নন।

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


64
"ছোট করুন" এর উপকারের জন্য +1 তবে একাধিক আয় নিষিদ্ধ নয়।
রায়েডওয়াল্ড

13
"বোঝা শক্ত" খুব বিষয়ভিত্তিক, বিশেষত যখন লেখক সাধারণ দাবির পক্ষে সমর্থন করার জন্য কোনও অনুপ্রেরণামূলক প্রমাণ সরবরাহ করেন না ... চূড়ান্ত রিটার্নের বিবরণের জন্য কোডে অনেক শর্তাধীন স্থানে সেট করা আবশ্যক একটি একক ভেরিয়েবল সমানভাবে সাপেক্ষে "সম্ভাব্যতা সম্পর্কে অজানা যে চলকটি তার কার্যকারিতার উপরে কোথাও নির্ধারিত হয়েছিল!
হেস্টন টি। হল্টম্যান

26
ব্যক্তিগতভাবে, আমি যেখানে সম্ভব সম্ভব তাড়াতাড়ি ফিরে আসার পক্ষপাতী। কেন? ঠিক আছে, যখন আপনি কোনও প্রদত্ত মামলার রিটার্ন কীওয়ার্ডটি দেখেন, আপনি তাত্ক্ষণিকভাবে "আমি শেষ হয়ে গেছি" তা জানতে পারবেন - এরপরে কী ঘটেছিল তা যদি কিছু হয় তবে তা জানতে আপনাকে পড়া চালিয়ে চলতে হবে না।
সিম্পসন

12
@ HestonT.Holtmann: জিনিস যে প্রণীত কোড সম্পূর্ণ হয়েছে প্রোগ্রামিং বই মধ্যে অনন্য যে পরামর্শ ছিল হয় গবেষণামূলক প্রমাণ দ্বারা ব্যাক।
অ্যাড্রিয়ান ম্যাকার্থি

9
এটি সম্ভবত গ্রহণযোগ্য উত্তর হওয়া উচিত, কারণ এতে উল্লেখ করা হয়েছে যে একাধিক রিটার্ন পয়েন্ট থাকা সবসময় ভাল না, তবুও কখনও কখনও প্রয়োজনীয় হয় sometimes
রাফিদ

229

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

string fooBar(string s, int? i) {
  string ret = "";
  if(!string.IsNullOrEmpty(s) && i != null) {
    var res = someFunction(s, i);

    bool passed = true;
    foreach(var r in res) {
      if(!r.Passed) {
        passed = false;
        break;
      }
    }

    if(passed) {
      // Rest of code...
    }
  }

  return ret;
}

কোড যেখানে একাধিক প্রস্থান বিন্দু এই তুলনা করা হয় অনুমতি: -

string fooBar(string s, int? i) {
  var ret = "";
  if(string.IsNullOrEmpty(s) || i == null) return null;

  var res = someFunction(s, i);

  foreach(var r in res) {
      if(!r.Passed) return null;
  }

  // Rest of code...

  return ret;
}

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


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

7
প্রথমত, এটি নিখুঁত উদাহরণ। দ্বিতীয়ত, স্ট্রিং রেট; "দ্বিতীয় সংস্করণে কোথায় যায়? তৃতীয়, রেটে কোনও দরকারী তথ্য নেই th চতুর্থ, কেন একটি ফাংশন / পদ্ধতিতে এত যুক্তি? পঞ্চম, কেন ডিডভ্যালিউসপাস (টাইপ রেস) না করে রেস্টওফকোড () আলাদা করবেন না? subfunifications?
রিক মিনারিচ

25
@ রিক ১. আমার অভিজ্ঞতায় রূপান্তরিত নয়, এটি আসলে এমন একটি প্যাটার্ন যা আমি বহুবার এসেছি, ২. এটি 'বাকী কোডে' বরাদ্দ করা হয়েছে, সম্ভবত এটি পরিষ্কার নয়। Um.উম? এটা উদাহরণ? ৪. ঠিক আছে, আমি অনুমান করি যে এটি এই সম্মানের সাথে সংযুক্ত, তবে এটি অনেকটা ন্যায্যতা প্রমাণ করা সম্ভব, ৫. করতে পারত ...
ljs

5
@ রিক পয়েন্টটি হ'ল একটি বিশাল বিবৃতিতে কোড গুটিয়ে ফেলার চেয়ে প্রায়শই প্রথম দিকে ফিরে আসা সহজ। এটি আমার অভিজ্ঞতায় অনেকটা আসে, এমনকি সঠিক রিফ্যাক্টরিংয়ের সাথেও।
ljs

5
একাধিক রিটার্নের স্টেটমেন্ট না রাখার বিষয়টি হ'ল ডিবাগিংকে সহজ করে তোলে, এটি পঠনযোগ্যতার জন্য অনেক দূরে। শেষে একটি ব্রেকপয়েন্ট আপনাকে ছাড়ের মান দেখতে দেয়, ব্যতিক্রমগুলি সান করে দেয়। পাঠযোগ্যতার জন্য 2 প্রদর্শিত ফাংশনগুলি একই আচরণ করে না। ডিফল্ট রিটার্নটি যদি খালি স্ট্রিং হয়! R.Passed তবে "আরও পঠনযোগ্য" এক এটি নাল ফেরার জন্য পরিবর্তন করে। লেখক ভুল লেখেন যে এর আগে কেবল কয়েকটি লাইনের পরে একটি ডিফল্ট ছিল। এমনকি তুচ্ছ উদাহরণে অস্পষ্ট ডিফল্ট রিটার্ন পাওয়া সহজ, শেষে একক রিটার্ন প্রয়োগ করা কার্যকর করতে সহায়তা করে।
মিচ

191

আমি বর্তমানে এমন একটি কোডবেসে কাজ করছি যেখানে এতে কাজ করা দু'জন লোক অন্ধভাবে "একক পয়েন্টের প্রস্থান" তত্ত্বের সাবস্ক্রাইব করেছে এবং আমি আপনাকে বলতে পারি যে অভিজ্ঞতা থেকে এটি একটি ভয়ঙ্কর ভয়ঙ্কর অনুশীলন। কোডটি বজায় রাখা অত্যন্ত কঠিন করে তোলে এবং কেন তা আপনাকে দেখাব।

"একক পয়েন্টের প্রস্থান" তত্ত্বের সাহায্যে, আপনি অনিবার্যভাবে এমন কোডের সাথে সজ্জিত হন যা দেখতে এইরকম লাগে:

function()
{
    HRESULT error = S_OK;

    if(SUCCEEDED(Operation1()))
    {
        if(SUCCEEDED(Operation2()))
        {
            if(SUCCEEDED(Operation3()))
            {
                if(SUCCEEDED(Operation4()))
                {
                }
                else
                {
                    error = OPERATION4FAILED;
                }
            }
            else
            {
                error = OPERATION3FAILED;
            }
        }
        else
        {
            error = OPERATION2FAILED;
        }
    }
    else
    {
        error = OPERATION1FAILED;
    }

    return error;
}

এটি কেবল কোডটি অনুসরণ করা খুব কঠিন করে না, তবে পরে বলুন আপনাকে ফিরে যেতে হবে এবং 1 এবং 2 এর মধ্যে একটি অপারেশন যুক্ত করতে হবে আপনাকে পুরো ফ্রেইকিং ফাংশনটি সম্পর্কে ইন্ডেন্ট করতে হবে, এবং সৌভাগ্য যে সমস্ত নিশ্চিত করে আপনার যদি / অন্য শর্ত এবং ধনুর্বন্ধনী সঠিকভাবে মিলে যায়।

এই পদ্ধতিটি কোড রক্ষণাবেক্ষণকে অত্যন্ত কঠিন এবং ত্রুটির প্রবণ করে তোলে।


5
@ মুর্ফ: আপনার জানার কোনও উপায় নেই যে প্রতিটি শর্তের পরে পড়া না করেই আর কিছুই ঘটে না। সাধারণত আমি বলব এই ধরণের বিষয়গুলি বিষয়গত, তবে এটি কেবল স্পষ্টতই ভুল। প্রতিটি ত্রুটি ফিরে পাওয়ার সাথে সাথে আপনি শেষ হয়ে গেছেন, ঠিক কী হয়েছিল তা আপনি জানেন।
জিওচেট

6
@ মুর্ফ: আমি এই ধরণের কোড ব্যবহার, অপব্যবহার এবং অতিরিক্ত ব্যবহৃত দেখেছি। উদাহরণটি বেশ সহজ, কারণ ভিতরে / অন্য কোনও ক্ষেত্রে সত্য নেই। এই ধরণের কোডটি ভেঙে ফেলার যে সমস্ত দরকার তা হ'ল একটি "অন্য" ভুলে যাওয়া। আফাইক, এই কোডটি ব্যতিক্রমগুলির সত্যিকারের খারাপ প্রয়োজন।
প্যারাসেবল

15
আপনি এটিতে এটি রিফ্যাক্টর করতে পারেন, এটির "বিশুদ্ধতা" রাখে: যদি (! SUCCEEDED (অপারেশন 1 ()) {} অন্য ত্রুটি = অপারেশন 1 ফায়াল্ড; if (ত্রুটি! = এস_ओকে) {যদি (SUCCEEDED (অপারেশন 2 ()))} অন্য ত্রুটি = অপারেশন 2 ফায়াল্ড; } if (ত্রুটি! = S_OK) {যদি (SUCCEEDED (অপারেশন 3 ())) {অন্য ত্রুটি = অপারেশন 3 ফায়াল্ড; } // ইত্যাদি।
জো পাইনেদা

6
এই কোডটিতে কেবল একটি প্রস্থান বিন্দু নেই: এই "ত্রুটি =" বিবৃতিগুলির প্রত্যেকটি একটি প্রস্থান পথে রয়েছে। এটি কেবল ফাংশন থেকে বেরিয়ে আসার কথা নয়, এটি কোনও ব্লক বা ক্রম থেকে বেরিয়ে আসা সম্পর্কে।
জে বাজুজি

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

72

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


44
স্ট্রাকচার্ড প্রোগ্রামিং কোনও কথা বলে না। কাঠামোগত প্রোগ্রামিংয়ের সমর্থক হিসাবে নিজেকে বর্ণনা করে এমন কিছু (তবে সমস্ত নয়) এমন লোক বলে।
জান্নাত

15
"আপনি যদি তাঁর অন্যান্য পরামর্শ অনুসরণ করেন এবং ছোট ফাংশনগুলি লেখেন তবে এটি ভালভাবে কাজ করে।" এটি সবচেয়ে গুরুত্বপূর্ণ বিষয়। ছোট ফাংশনগুলির জন্য খুব কমই রিটার্ন পয়েন্টের প্রয়োজন হয়।

6
@ নোনেস +1 মন্তব্যটির জন্য, তাই সত্য। সমস্ত "স্ট্রাক্টুড প্রোগ্রামিং" বলছে GOTO ব্যবহার করবেন না।
paxos1977

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

1
"কোডের 'কাঠামো' উপেক্ষা করার বিষয়েই রয়েছে are" - না, একেবারে বিপরীত। "তাদের এড়িয়ে চলা উচিত বলে বোঝা যায়" - না, তা হয় না।
জিম বাল্টার

62

ক্যান্ট বেক নোট হিসাবে যেমন ইমপ্লিমেন্টেশন প্যাটার্নগুলিতে একটি গার্ডেন তৈরির ক্ষেত্রে প্রহরী ধারাগুলির বিষয়ে আলোচনা করার সময় একটি একক প্রবেশ এবং প্রস্থান পয়েন্ট থাকে ...

"একই রুটিনে অনেক লোকের মধ্যে ঝাঁপিয়ে পড়ার সময় সম্ভব হওয়া বিভ্রান্তি রোধ করা ছিল। ফোরট্রান বা অ্যাসেম্বলি ভাষার প্রোগ্রামগুলিতে প্রচুর বৈশ্বিক ডেটা সহ লেখা যখন এটি প্রয়োগ করা হয়েছিল তখনও বোঝা যায় যে কোন বিবৃতি কার্যকর হয়েছিল তা বোঝাও কঠোর পরিশ্রম ছিল .." "ছোট পদ্ধতি এবং বেশিরভাগ স্থানীয় ডেটা সহ এটি অযথা রক্ষণশীল" "

আমি গার্ড ক্লজগুলির সাথে লিখিত একটি ফাংশনটি দেখতে পাই যা দীর্ঘ দীর্ঘ নেস্টেড if then elseবিবৃতিগুলির চেয়ে আরও বেশি সহজে অনুসরণ করা যায় ।


অবশ্যই, "যদি-তবে-অন্য বিবৃতিগুলির একটি দীর্ঘ নেস্টেড গুচ্ছ" গার্ড ক্লজগুলির একমাত্র বিকল্প নয়।
এড্রিয়ান ম্যাকার্থি

@ অ্যাড্রিয়ানমিসার্থী আপনার কাছে কি আরও ভাল বিকল্প আছে? এটি ব্যঙ্গাত্মক চেয়ে বেশি দরকারী হবে।
শিনজৌ

@ কুহাকু: আমি নিশ্চিত নই যে আমি এই কটাক্ষ বলি। উত্তরটি পরামর্শ দেয় যে এটি উভয়ই / অথবা পরিস্থিতি: হয় গার্ড ক্লজ বা দীর্ঘ-নেস্টেড গুচ্ছগুলি যদি-তবে-অন্যথায় হয়। অনেকগুলি (সর্বাধিক?) প্রোগ্রামিং ল্যাঙ্গুয়েজ গার্ডের ক্লজ ছাড়াও এই জাতীয় যুক্তিকে ফ্যাক্ট করার বিভিন্ন উপায় সরবরাহ করে।
অ্যাড্রিয়ান ম্যাকার্থি

61

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

অন্য কথায়, যখন সম্ভব হয়, এই শৈলীর পক্ষে

return a > 0 ?
  positively(a):
  negatively(a);

এটার উপরে

if (a > 0)
  return positively(a);
else
  return negatively(a);

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

এমন কোনও কঠোর এবং দ্রুত নিয়ম নেই যা প্রতিটি ভাষার ক্ষেত্রে প্রযোজ্য। একক রিটার্ন স্টেটমেন্ট থাকার মতো কিছু আপনার কোডটি ভাল করবে না। তবে ভাল কোড আপনাকে আপনার ফাংশনগুলি সেভাবে লিখতে দেয়।


6
+1 "যদি আপনি দেখতে পান যে আপনার আইএফস এবং এলিসগুলি সিনট্যাক্টিকভাবে অনেক দূরে রয়েছে, তবে আপনি এটিকে ছোট ফাংশনে বিভক্ত করতে চাইতে পারেন" "
আন্দ্রেস জান ট্যাক

4
+1, যদি এটি সমস্যা হয় তবে এর অর্থ সাধারণত আপনি একক ফাংশনে খুব বেশি করছেন। এটি সত্যিই আমাকে হতাশ করেছে যে এটি সর্বাধিক ভোট দেওয়া উত্তর নয়
ম্যাট ব্রিগস

1
গার্ডের বিবৃতিগুলির কোনও পার্শ্ব প্রতিক্রিয়া নেই, তবে বেশিরভাগ লোক এগুলি দরকারী হিসাবে বিবেচনা করবে। সুতরাং কোনও পার্শ্ব প্রতিক্রিয়া না থাকলেও তাড়াতাড়ি ফাঁসি কার্যকর করার কারণ থাকতে পারে। এই উত্তরটি আমার মতে ইস্যুটির পুরোপুরি সমাধান করে না।
মার্টেন বোদেউয়েস


43

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


ঠিক আছে, যদিও আমি বিশ্বাস করি যে অত্যন্ত অপ্টিমাইজড কোড (যেমন সফ্টওয়্যার স্কিনিং কমপ্লেক্স 3 ডি মেসেস!) লেখার চেষ্টা করার সময় মুছে ফেলাগুলি অনুলিপি করা ভাল
গ্রান্ট পিটার্স

1
কী কারণে আপনি বিশ্বাস করতে পারেন? আপনার যদি দুর্বল অপ্টিমাইজেশান সহ একটি সংকলক থাকে যেখানে ডিফারেন্সিংয়ের ক্ষেত্রে কিছু ওভারহেড থাকে তবে auto_ptrআপনি সমান্তরালে প্লেইন পয়েন্টার ব্যবহার করতে পারেন। যদিও এটি প্রথম স্থানে একটি অপ্টিমাইটিজ সংকলক সহ 'অপ্টিমাইজড' কোড লেখা অদ্ভুত হবে।
পিট কির্খাম

এটি নিয়মটিতে একটি আকর্ষণীয় ব্যতিক্রম ঘটায়: আপনার প্রোগ্রামিং ভাষায় যদি এমন কিছু না থাকে যা স্বয়ংক্রিয়ভাবে পদ্ধতির শেষে বলা হয় (যেমন try... finallyজাভাতে) এবং আপনাকে সংস্থান রক্ষণাবেক্ষণ করতে হবে যা আপনি একটি একক দিয়ে করতে পারেন একটি পদ্ধতি শেষে ফিরে। আপনি এটি করার আগে, পরিস্থিতি থেকে মুক্তি পাওয়ার জন্য আপনার কোডটি রিফ্যাকচারিংয়ের গুরুত্ব সহকারে বিবেচনা করা উচিত।
মার্টেন বোদেউয়েস

@ পেটকিরখাম @ ক্লিনআপ কেন খারাপ? হ্যাঁ গোটোটি খারাপভাবে ব্যবহার করা যেতে পারে তবে এই বিশেষ ব্যবহারটি খারাপ নয়।
q126y

1
@ Q126y সি ++ এ, RAII এর বিপরীতে, ব্যতিক্রম নিক্ষেপ করলে এটি ব্যর্থ হয়। সি তে, এটি একটি সম্পূর্ণ বৈধ অভ্যাস। দেখুন stackoverflow.com/questions/379172/use-goto-or-not
পিট Kirkham

40

আমি এই ধারনাটির দিকে ঝুঁকেছি যে ফাংশনের মাঝখানে রিটার্নের স্টেটমেন্টগুলি খারাপ। আপনি ফাংশনটির শীর্ষে কয়েকটি গার্ড ক্লজ তৈরি করতে রিটার্নগুলি ব্যবহার করতে পারেন, এবং অবশ্যই ইস্যু ছাড়াই ফাংশন শেষে কী ফিরে আসবে তা সংকলককে জানান, তবে ফাংশনের মাঝামাঝি রিটার্নগুলি মিস করা সহজ হতে পারে এবং ফাংশনটি ব্যাখ্যা করতে শক্ত করুন।


38

কোনও কার্যক্রমে কেবলমাত্র একটি রিটার্নের বিবৃতি দেওয়া ভাল অভ্যাসের ভাল কারণ রয়েছে?

হ্যাঁ , আছে:

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

প্রশ্নটি প্রায়শই একাধিক রিটার্নের মধ্যে একটি মিথ্যা দ্বিবিজ্ঞান হিসাবে উত্থাপিত হয় বা বিবৃতি দিলে গভীরভাবে বাসা বেঁধে থাকে। প্রায় সবসময়ই একটি তৃতীয় সমাধান থাকে যা একমাত্র প্রস্থান পয়েন্ট সহ খুব লিনিয়ার (গভীর বাসা বাঁধে না)।

আপডেট : দৃশ্যত MISRA নির্দেশিকা একক প্রস্থানকেও প্রচার করে।

স্পষ্টতই, আমি বলছি না যে একাধিক রিটার্ন পাওয়া সর্বদা ভুল। তবে অন্যথায় সমতুল্য সমাধান দেওয়া, একক রিটার্নের সাথে একটিকে পছন্দ করার জন্য অনেকগুলি ভাল কারণ রয়েছে।


2
আর একটি ভাল কারণ, সম্ভবত সেরা দিনগুলি, একক রিটার্নের স্টেটমেন্টটি লগইন করা। আপনি যদি কোনও পদ্ধতিতে লগিং যুক্ত করতে চান তবে আপনি একটি একক লগ স্টেটমেন্ট রাখতে পারেন যা পদ্ধতিটি কী দেয় তা বোঝায়।
inor

ফরটারান প্রবেশ বিবৃতিটি কতটা সাধারণ ছিল? Docs.oracle.com/cd/E19957-01/805-4939/6j4m0vn99/index.html দেখুন । এবং যদি আপনি সাহসী হন তবে আপনি এওপি এবং পরামর্শের পরে পদ্ধতিগুলি লগ করতে পারেন
এরিক জাবলো

1
+1 প্রথম 2 পয়েন্টগুলি আমাকে বোঝানোর জন্য যথেষ্ট ছিল। এটি দ্বিতীয় শেষ অনুচ্ছেদের সাথে। আমি লগিং উপাদানটির সাথে একই কারণে দ্বিমত পোষণ করব যেহেতু আমি গভীর নেস্টেড শর্তাদিকে নিরুৎসাহিত করি কারণ তারা একক দায়িত্বের নিয়মকে ভঙ্গ করতে উত্সাহিত করে যা মূল কারণ হ'ল পলিমারফিজমটি ওওপি-র মধ্যে প্রবর্তিত হয়েছিল।
ফ্রান্সিস রজার্স

আমি কেবল এটি সি # এবং কোড চুক্তিগুলির সাথে যুক্ত করতে চাই, শর্ত-পরবর্তী সমস্যাটি একটি অজানা, যেহেতু আপনি এখনও Contract.Ensuresএকাধিক রিটার্ন পয়েন্ট ব্যবহার করতে পারেন ।
জুলাইলগন

1
@ q126y: আপনি যদি gotoসাধারণ ক্লিনআপ কোডটি পেতে ব্যবহার করে থাকেন তবে আপনি সম্ভবত ফাংশনটি সহজ করেছেন যাতে returnক্লিন-আপ কোডের শেষে একটি একক থাকে। সুতরাং আপনি বলতে পারেন যে আপনি সমস্যার সমাধান করেছেন goto, তবে আমি বলতে চাই আপনি এটি একটির সরল করে সমাধান করেছেন return
অ্যাড্রিয়ান ম্যাকার্থি

33

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


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

3
হ্যাঁ. আমি এমন একটি সিস্টেমে লগিং কোড যুক্ত করছি যা মাঝেমধ্যে উত্পাদনে ভুল আচরণ করে (যেখানে আমি পদক্ষেপ নিতে পারি না)। পূর্ববর্তী কোডার যদি একক-প্রস্থান ব্যবহার করত তবে এটি খুব সহজ হত।
মাইকেল ব্ল্যাকবার্ন

3
সত্য, ডিবাগ করার ক্ষেত্রে এটি সহায়ক। তবে বাস্তবে আমি বেশিরভাগ ক্ষেত্রেই কল করার পরে, কল করার পরে - কার্যকরভাবে একই ফলাফলের জন্য ব্রেকপয়েন্ট স্থাপন করতে সক্ষম হয়েছি। (এবং সেই অবস্থানটি অবশ্যই কল স্ট্যাকের সাথে পাওয়া যায়)) ওয়াইএমএমভি।
foo

এটি হ'ল যদি না আপনার ডিবাগার স্টেপ-আউট বা স্টেপ-রিটার্ন ফাংশন সরবরাহ করে (এবং প্রতিটি ডিবাগার আমার জানা মতে কাজ করে), যা প্রত্যাবর্তনের পরে ডানদিকের মানটি দেখায় । এর পরে মান পরিবর্তন করা কিছুটা জটিল হতে পারে যদিও এটি যদি কোনও ভেরিয়েবলের জন্য বরাদ্দ না করা হয়।
মার্টেন বোদেউয়েস

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

19

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


"সাধারণভাবে আমি একটি ফাংশন থেকে কেবল একটি একক বহির্গমন পয়েন্ট পেতে চেষ্টা করি" - কেন? "লক্ষ্যটি যতটা সম্ভব কম কয়েকটি বহির্গমন পয়েন্ট হওয়া উচিত" - কেন? এবং 19 জন লোক কেন এই উত্তরহীনকে ভোট দিয়েছে?
জিম বাল্টার

@ জিমবাল্টার শেষ পর্যন্ত, এটি ব্যক্তিগত পছন্দের দিকে ফোটে। আরও বেশি প্রস্থান পয়েন্টগুলি সাধারণত আরও জটিল পদ্ধতির দিকে পরিচালিত করে (যদিও সবসময় না) এবং কারও পক্ষে বোঝা আরও জটিল করে তোলে।
স্কট ডরম্যান

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

14

না, কারণ আমরা আর 1970 এর দশকে বাস করি না । যদি আপনার ফাংশনটি এত দীর্ঘ হয় যে একাধিক রিটার্ন একটি সমস্যা হয় তবে এটি খুব দীর্ঘ।

(এক্ষেত্রে ব্যতিক্রম ছাড়া কোনও ভাষাতে যে কোনও মাল্টি-লাইন ফাংশনের একাধিক প্রস্থান পয়েন্ট থাকবে তা বাদ দিয়ে) have


14

আমার পছন্দটি একক প্রস্থানের জন্য হবে যদি না এটি সত্যিই জিনিসগুলিকে জটিল করে তোলে। আমি খুঁজে পেয়েছি যে কিছু ক্ষেত্রে, একাধিক উপস্থিতি পয়েন্টগুলি আরও আরও উল্লেখযোগ্য ডিজাইনের সমস্যাগুলি মাস্ক করতে পারে:

public void DoStuff(Foo foo)
{
    if (foo == null) return;
}

এই কোডটি দেখার পরে, আমি অবিলম্বে জিজ্ঞাসা করব:

  • 'ফু' কি কখনও নাল?
  • যদি তা হয় তবে 'ডোস্টফ'-এর কতজন ক্লায়েন্ট কোনও নাল' ফু 'দিয়ে ফাংশনটি কল করে?

এই প্রশ্নের উত্তরগুলির উপর নির্ভর করে এটি হতে পারে

  1. চেকটি অর্থহীন কারণ এটি কখনই সত্য নয় (যেমন, এটি একটি দৃ as়তা হওয়া উচিত)
  2. চেকটি খুব কমই সত্য এবং তাই সেই নির্দিষ্ট কলারের ফাংশনগুলি পরিবর্তন করা ভাল কারণ তাদের সম্ভবত অন্য কোনও পদক্ষেপ নেওয়া উচিত।

উপরের উভয় ক্ষেত্রেই সম্ভবত কোডটি একটি দৃked়তার সাথে পুনরায় কাজ করা যেতে পারে যাতে 'foo' কখনই বাতিল হয় না এবং প্রাসঙ্গিক কলারগুলি পরিবর্তিত হয় তা নিশ্চিত করা যায়।

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

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

void foo (int i, int j) {
  A a;
  if (i > 0) {
     B b;
     return ;   // Call dtor for 'b' followed by 'a'
  }
  if (i == j) {
     C c;
     B b;
     return ;   // Call dtor for 'b', 'c' and then 'a'
  }
  return 'a'    // Call dtor for 'a'
}

কোডের আকারটি যদি কোনও সমস্যা হয় - তবে এটি এড়ানোর মতো কিছু হতে পারে।

অন্যান্য সমস্যাটি "নামযুক্ত রিটার্ন মান অপটিমিজেশন" (ওরফে অনুলিপি এলিজেন, আইএসও সি ++ ''03 12.8 / 15) সম্পর্কিত। সি ++ কোনও প্রয়োগকে কপি কন্সট্রাক্টরকে কল করতে এড়াতে অনুমতি দেয় যদি তা করতে পারে:

A foo () {
  A a1;
  // do something
  return a1;
}

void bar () {
  A a2 ( foo() );
}

কোডটি যেমন হয় তেমন 'a1' অবজেক্টটি 'foo' তে নির্মিত হয় এবং তার কপির কন্ট্রাক্টকে 'a2' বানানোর জন্য ডাকা হবে। তবে অনুলিপি এলিজেন সংকলককে স্ট্যাকের 'a2' হিসাবে একই জায়গায় 'a1' নির্মাণের অনুমতি দেয়। সুতরাং ফাংশনটি ফিরে আসার পরে অবজেক্টটির "অনুলিপি" করার দরকার নেই।

একাধিক প্রস্থান পয়েন্টগুলি এটি সনাক্ত করার চেষ্টা করে সংকলকটির কাজকে জটিল করে তোলে এবং কমপক্ষে ভিসি ++ এর অপেক্ষাকৃত সাম্প্রতিক সংস্করণের জন্য অপ্টিমাইজেশানটি ঘটেনি যেখানে ফাংশন বডিটিতে একাধিক রিটার্ন ছিল। দেখুন ভিসুয়াল C ++ 2005 নামযুক্ত ফেরত মান অপ্টিমাইজেশান আরো বিস্তারিত জানার জন্য।


1
আপনি যদি আপনার সি ++ উদাহরণের বাইরে সর্বশেষ ডেটর বাদে সমস্ত কিছু নেন তবে বি এবং পরে সি এবং বি ধ্বংস করার কোডটি যদি এখনও যদি বিবৃতিটির পরিধিটি শেষ হয় তবে উত্পন্ন করতে হবে, তাই আপনি একাধিক রিটার্ন না পেয়ে সত্যিই কিছু অর্জন করতে পারবেন না ।
অন্ধকার

4
+1 এবং নীচে নীচে waaaaay আমাদের কোডিং অনুশীলন বিদ্যমান থাকার কারণ আছে - এনআরভিও। তবে এটি একটি মাইক্রো-অপটিমাইজেশন; এবং, সমস্ত মাইক্রো-অপ্টিমাইজেশান অনুশীলনের মতোই সম্ভবত প্রায় 50 বছর বয়সী "বিশেষজ্ঞ" দ্বারা সূচিত হয়েছিল যিনি 300 কেএইচজেড পিডিপি -8 এ প্রোগ্রামিংয়ে অভ্যস্ত, এবং পরিষ্কার এবং কাঠামোগত কোডের গুরুত্ব বোঝেন না। সাধারণভাবে ক্রিস এস-এর পরামর্শ নিন এবং যখনই তা বোঝা যায় তখন একাধিক রিটার্ন স্টেটমেন্ট ব্যবহার করুন।
ব্লুরাজা - ড্যানি প্লেফুঘুফুট

যদিও আমি আপনার পছন্দটির সাথে একমত নই (মনে মনে, আপনার দৃsert় পরামর্শটি একটি রিটার্ন পয়েন্টও, যেমন throw new ArgumentNullException()এই ক্ষেত্রে সি # তে রয়েছে), আমি আপনার অন্যান্য বিবেচ্য বিষয়গুলি সত্যই পছন্দ করেছি, সেগুলি আমার কাছে বৈধ, এবং কিছু ক্ষেত্রে সমালোচনাও হতে পারে কুলুঙ্গি প্রসঙ্গ।
জুলাইলগন

এটি স্ট্রোম্যান দিয়ে পূর্ণ ock কেন fooপরীক্ষা করা হচ্ছে এই প্রশ্নের সাথে এই বিষয়ের কোনও যোগসূত্র নেই, যা করা if (foo == NULL) return; dowork; বা করা উচিতif (foo != NULL) { dowork; }
জিম বাল্টার

11

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


খুব অন্তর্দৃষ্টিপূর্ণ। যদিও, আমি অনুভব করি যে কোনও প্রোগ্রামার যখন একাধিক বহির্গমন পয়েন্টগুলি ব্যবহার করবেন তা না জানা পর্যন্ত তাদের সীমাবদ্ধ থাকা উচিত।
রিক মিনারিচ

5
আসলে তা না. "যদি (...) ফিরে আসে; ... প্রত্যাবর্তন;" এর চক্রবৃত্তীয় জটিলতা "যদি (...) {...} প্রত্যাবর্তন;" হিসাবে একই। তাদের দুজনেরই দুটি পথ রয়েছে।
স্টিভ এমারসন

11

আমি নিজেকে কেবল একটি returnবিবৃতি ব্যবহার করতে বাধ্য করি , কারণ এটি একটি অর্থে কোডের গন্ধ তৈরি করে। আমাকে বিস্তারিত বলতে দাও:

function isCorrect($param1, $param2, $param3) {
    $toret = false;
    if ($param1 != $param2) {
        if ($param1 == ($param3 * 2)) {
            if ($param2 == ($param3 / 3)) {
                $toret = true;
            } else {
                $error = 'Error 3';
            }
        } else {
            $error = 'Error 2';
        }
    } else {
        $error = 'Error 1';
    }
    return $toret;
}

(শর্তগুলি আরব্রিটরি ...)

যত বেশি শর্ত হয়, ফাংশনটি তত বড় হয়, পড়তে তত বেশি কষ্ট হয়। সুতরাং আপনি যদি কোডের গন্ধে সজ্জিত হন তবে আপনি এটি উপলব্ধি করতে পারবেন এবং কোডটি রিফ্যাক্টর করতে চান। দুটি সম্ভাব্য সমাধান হ'ল:

  • একাধিক রিটার্ন
  • পৃথক ফাংশন মধ্যে রিফ্যাক্টরিং

একাধিক রিটার্ন

function isCorrect($param1, $param2, $param3) {
    if ($param1 == $param2)       { $error = 'Error 1'; return false; }
    if ($param1 != ($param3 * 2)) { $error = 'Error 2'; return false; }
    if ($param2 != ($param3 / 3)) { $error = 'Error 3'; return false; }
    return true;
}

পৃথক ফাংশন

function isEqual($param1, $param2) {
    return $param1 == $param2;
}

function isDouble($param1, $param2) {
    return $param1 == ($param2 * 2);
}

function isThird($param1, $param2) {
    return $param1 == ($param2 / 3);
}

function isCorrect($param1, $param2, $param3) {
    return !isEqual($param1, $param2)
        && isDouble($param1, $param3)
        && isThird($param2, $param3);
}

মঞ্জুর, এটি দীর্ঘ এবং কিছুটা অগোছালো তবে এইভাবে ফাংশনটি রিফ্যাক্টর করার প্রক্রিয়াতে আমরা করেছি've

  • পুনরায় ব্যবহারযোগ্য ফাংশন তৈরি করেছে,
  • ফাংশনটি আরও মানব পাঠযোগ্য, এবং
  • ফাংশনগুলির ফোকাস কেন মানগুলি সঠিক।

5
-1: খারাপ উদাহরণ। আপনি ত্রুটি বার্তা হ্যান্ডলিং বাদ দিয়েছেন। যদি এটির প্রয়োজন না হয় তবে সঠিকভাবে রিটার্ন এক্সএক্সএক্স & & y & zz; হিসাবে প্রকাশ করা যেতে পারে; যেখানে xx, yy এবং z হল একুয়াল, isDouble এবং isThird এক্সপ্রেশন।
কাউপ্পি

10

আমি বলব আপনার প্রয়োজনীয় সংখ্যক, বা কোড ক্লিনার তৈরির মতো কোনও হওয়া উচিত (যেমন গার্ডের ধারাগুলি )।

আমি কোনও "সেরা অনুশীলন" ব্যক্তিগতভাবে কখনও শুনিনি / দেখিনি যে আপনার কেবলমাত্র একটি রিটার্নের বিবৃতি থাকা উচিত।

বেশিরভাগ ক্ষেত্রে, আমি একটি যুক্তিযুক্ত পথের উপর ভিত্তি করে যত তাড়াতাড়ি সম্ভব একটি ফাংশন থেকে প্রস্থান করার প্রবণতা করেছি (গার্ড ক্লজগুলি এটির একটি দুর্দান্ত উদাহরণ)।


10

আমি বিশ্বাস করি যে একাধিক রিটার্ন সাধারণত ভাল হয় (কোডটি আমি সি # তে লিখি)। একক-ফেরত শৈলী হ'ল সি থেকে হোল্ডওভার But তবে আপনি সম্ভবত সি-তে কোডিং করছেন না probably

সমস্ত প্রোগ্রামিং ভাষায় কোনও পদ্ধতির জন্য কেবলমাত্র একটি প্রস্থান বিন্দুর প্রয়োজন নেই এমন আইন নেই । কিছু লোক এই শৈলীর শ্রেষ্ঠত্বের উপর জোর দেয় এবং কখনও কখনও তারা এটিকে একটি "বিধি" বা "আইন" হিসাবে উন্নীত করে তবে এই বিশ্বাস কোনও প্রমাণ বা গবেষণা দ্বারা সমর্থন করে না।

একাধিক রিটার্ন শৈলী সি কোডে একটি খারাপ অভ্যাস হতে পারে, যেখানে সংস্থানগুলি স্পষ্টতই ডি-বরাদ্দ করতে হয়, তবে জাভা, সি #, পাইথন বা জাভাস্ক্রিপ্টের মতো ভাষাতে যেমন স্বয়ংক্রিয় আবর্জনা সংগ্রহ এবং try..finallyব্লক (এবং usingসি # তে ব্লক) এর মতো নির্মাণ রয়েছে ), এবং এই যুক্তি প্রযোজ্য নয় - এই ভাষাগুলিতে কেন্দ্রীভূত ম্যানুয়াল রিসোর্স অবলোকনের প্রয়োজন খুব অস্বাভাবিক।

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

সুতরাং, আপনার শৈল্পিক সংবেদনশীলতা অনুসারে যতগুলি রিটার্ন ব্যবহার করুন, কারণ এটি কোনও প্রযুক্তিগত নয়, এটি একটি বিন্যাস এবং পাঠযোগ্যতার সমস্যা issue

আমি আমার ব্লগে আরও বেশি দৈর্ঘ্যে এ সম্পর্কে কথা বলেছি ।


10

অনিবার্য সম্পর্কে যেমন খারাপ কথা বলা হয় তেমনি একক বহির্গমন-পয়েন্ট সম্পর্কে বলার জন্য ভাল কথা রয়েছে "তীর" প্রোগ্রামিং সম্পর্কে ফলস্বরূপ that

ইনপুট বৈধতা বা সংস্থান বরাদ্দের সময় যদি একাধিক প্রস্থান পয়েন্টগুলি ব্যবহার করা হয়, তবে আমি সমস্ত 'ত্রুটি-প্রস্থান' খুব কার্যকরভাবে ফাংশনের শীর্ষে রাখার চেষ্টা করি।

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

আপনি যদি সত্যিই একক স্থানে রিসোর্সগুলি প্রকাশের জন্য উদাহরণস্বরূপ কোনও একক বহির্গমন (কোনও ব্যতিক্রম-অযোগ্য-সক্ষম ভাষায়) চান তবে আমি গোটার যত্ন সহকারে প্রয়োগটি ভাল হতে পারি; উদাহরণস্বরূপ দেখুন এটি বরং স্বীকৃত উদাহরণ (পর্দার রিয়েল এস্টেট সংরক্ষণের জন্য সংকুচিত):

int f(int y) {
    int value = -1;
    void *data = NULL;

    if (y < 0)
        goto clean;

    if ((data = malloc(123)) == NULL)
        goto clean;

    /* More code */

    value = 1;
clean:
   free(data);
   return value;
}

ব্যক্তিগতভাবে আমি সাধারণত একাধিক প্রস্থান-পয়েন্ট অপছন্দের চেয়ে অ্যারো প্রোগ্রামিংকে অপছন্দ করি না, যদিও সঠিকভাবে প্রয়োগ করার সময় উভয়ই কার্যকর। অবশ্যই সেরাটি হ'ল আপনার প্রোগ্রামটিকে কোনও প্রয়োজনের জন্যই গঠন করা। আপনার ফাংশনকে একাধিক অংশে ভাঙা সাধারণত সহায়তা করে :)

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

int g(int y) {
  value = 0;

  if ((value = g0(y, value)) == -1)
    return -1;

  if ((value = g1(y, value)) == -1)
    return -1;

  return g2(y, value);
}

প্রকল্প বা কোডিং নির্দেশিকাগুলির উপর নির্ভর করে, বেশিরভাগ বয়লার-প্লেট কোড ম্যাক্রোগুলির দ্বারা প্রতিস্থাপিত হতে পারে। পার্শ্ব নোট হিসাবে, এইভাবে এটি ভাঙ্গা ফাংশনগুলি g0, g1, g2 স্বতন্ত্রভাবে পরীক্ষা করা খুব সহজ করে তোলে।

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

সংক্ষেপে;

  • অনেক রিটার্নের তুলনায় কয়েকটি রিটার্নই ভাল
  • একাধিক রিটার্ন বিশাল তীরগুলির চেয়ে ভাল এবং গার্ডের ক্লজগুলি সাধারণত ঠিক থাকে।
  • সম্ভব হলে ব্যতিক্রমগুলি সম্ভবত বেশিরভাগ 'গার্ড ক্লজ' প্রতিস্থাপন করতে পারে / করা উচিত।

উদাহরণটি <y এর জন্য ক্র্যাশ হয়েছে, কারণ এটি NULL পয়েন্টারটি মুক্ত করার চেষ্টা করে ;-)
এরিক কিটজমুয়েলার

2
opengroup.org/onlinepubs/009695399/function/free.html " পিটিআরটি যদি নাল পয়েন্টার হয় তবে কোনও ক্রিয়াকলাপ ঘটবে না।"
হেনরিক গুস্তাফসন

1
না এটি ক্রাশ হবে না, কারণ NULL ফ্রিতে পাস করা একটি সংজ্ঞায়িত নো-অপশন। এটি একটি বিরক্তিকর সাধারণ ভুল ধারণা যা আপনাকে প্রথমে NULL এর জন্য পরীক্ষা করতে হবে।
hlovdal

"তীর" প্যাটার্ন কোনও অনিবার্য বিকল্প নয়। এটি একটি মিথ্যা বৈপরীত্য।
অ্যাড্রিয়ান ম্যাকার্থি

9

আপনি প্রবাদটি জানেন - সৌন্দর্য দর্শকের চোখে পড়ে

কিছু লোক নেটবিয়ান এবং কেউ ইন্টেলিজ আইডিইএ , কেউ পাইথনের এবং কেউ পিএইচপি-র কসম খায় ।

কিছু দোকানে আপনি যদি এই কাজটি করার জন্য জিদ করেন তবে আপনি আপনার চাকরি হারাতে পারেন:

public void hello()
{
   if (....)
   {
      ....
   }
}

প্রশ্ন সমস্ত দৃশ্যমানতা এবং রক্ষণাবেক্ষণযোগ্যতা সম্পর্কে।

যুক্তি এবং রাষ্ট্রীয় মেশিনের ব্যবহারকে হ্রাস ও সরল করতে আমি বুলিয়ান বীজগণিত ব্যবহারে আসক্ত। তবে, এমন অতীতের সহকর্মীরা ছিলেন যারা বিশ্বাস করেছিলেন কোডিংয়ে আমার "গাণিতিক কৌশল" ব্যবহার করা অনুপযুক্ত, কারণ এটি দৃশ্যমান এবং রক্ষণাবেক্ষণযোগ্য হবে না। এবং এটি একটি খারাপ অভ্যাস হবে। দুঃখিত লোকেরা, আমি নিযুক্ত কৌশলগুলি আমার কাছে অত্যন্ত দৃশ্যমান এবং রক্ষণাবেক্ষণযোগ্য - কারণ যখন আমি ছয় মাস পরে কোডটিতে ফিরে আসি তখন প্রবাদ বাক্যটি স্প্যাগেটির জগাখিচুড়ি দেখে আমি কোডটি স্পষ্টভাবে বুঝতে পারি।

আরে বন্ধু (প্রাক্তন ক্লায়েন্টের মতো বলতেন) আপনি যা চান তা করুন যতক্ষণ আপনি জানেন যে এটি ঠিক করার দরকার যখন আমার দরকার হয় it

আমার মনে আছে 20 বছর আগে আমার এক সহকর্মীকে চাকরীর জন্য বরখাস্ত করা হয়েছিল যা আজকে চতুর বিকাশ কৌশল হিসাবে ডাকা হবে । তাঁর একটি ক্ষুদ্রতর ইনক্রিমেন্টাল পরিকল্পনা ছিল। তবে তার পরিচালক তাকে চিত্কার করে বললেন "আপনি ব্যবহারকারীদের জন্য ক্রমবর্ধমান বৈশিষ্ট্যগুলি প্রকাশ করতে পারবেন না! আপনাকে অবশ্যই জলপ্রপাতের সাথে লেগে থাকতে হবে ।" পরিচালকের প্রতি তার প্রতিক্রিয়া ছিল যে ক্রমবর্ধমান বিকাশ গ্রাহকের প্রয়োজনের জন্য আরও সুনির্দিষ্ট হবে। তিনি গ্রাহকদের প্রয়োজনের বিকাশে বিশ্বাসী, তবে ম্যানেজার "গ্রাহকের প্রয়োজন" কোডিংয়ে বিশ্বাসী।

ডেটা নরমালাইজেশন, এমভিপি এবং এমভিসি সীমানা ভঙ্গ করার জন্য আমরা প্রায়শই দোষী । আমরা কোনও ফাংশন নির্মাণের পরিবর্তে ইনলাইন করি। আমরা শর্টকাট নিই।

ব্যক্তিগতভাবে, আমি বিশ্বাস করি যে পিএইচপি খারাপ অভ্যাস, তবে আমি কী জানি। সমস্ত তাত্ত্বিক যুক্তি নিয়মের একটি সেট পূরণ করার চেষ্টা করে

গুণমান = নির্ভুলতা, রক্ষণাবেক্ষণযোগ্যতা এবং লাভজনকতা।

অন্যান্য সমস্ত নিয়মগুলি পটভূমিতে বিবর্ণ হয়। এবং অবশ্যই এই নিয়মটি কখনই ম্লান হয় না:

অলসতা একটি ভাল প্রোগ্রামারের গুণাবলী।


1
"আরে বন্ধু (প্রাক্তন ক্লায়েন্টের মতো বলত) আপনি যা চান তা করুন যতক্ষণ আপনি জানেন যে এটি ঠিক করার জন্য যখন আমার দরকার হয় তখন এটি কীভাবে ঠিক করতে হয়।" সমস্যা: এটি প্রায়শই আপনি ঠিক করেন না।
ড্যান ব্যারন

এই উত্তরটিতে +1 কারণ আপনি কোথায় যাচ্ছেন তা নিয়ে আমি একমত কিন্তু আপনি কীভাবে সেখানে পৌঁছবেন তা অগত্যা নয়। আমি তর্ক করব যে বোঝার স্তর রয়েছে। অর্থ্যাৎ যে কর্মচারী এ 5 বছরের প্রোগ্রামিংয়ের অভিজ্ঞতা এবং 5 বছর কোনও সংস্থার সাথে রয়েছে তা বোঝা কর্মচারী বিয়ের চেয়ে খুব আলাদা, একটি কলেজ থেকে সবে শুরু হওয়া নতুন কলেজ স্নাতক। আমার বক্তব্যটি হ'ল যদি কর্মচারী এ কেবলমাত্র লোকজন যারা কোডটি বুঝতে পারে তবে এটি রক্ষণাবেক্ষণযোগ্য নয় এবং তাই আমাদের সকলের কোডটি লেখার জন্য প্রচেষ্টা করা উচিত যা কর্মচারী বি বুঝতে পারে। এখানেই আসল শিল্পটি সফ্টওয়্যারটিতে রয়েছে।
ফ্রান্সিস রজার্স

9

আমি প্রারম্ভিক ক্লজগুলি ব্যবহার শুরু করার দিকে ঝুঁকির সাথে তাড়াতাড়ি ফিরে আসুন এবং অন্যথায় কোনও পদ্ধতি শেষে প্রস্থান করুন। একক প্রবেশ এবং প্রস্থান নিয়মের historicalতিহাসিক তাত্পর্য রয়েছে এবং একাধিক রিটার্ন (এবং অনেকগুলি ত্রুটি) সহ একক সি ++ পদ্ধতির জন্য 10 A4 পৃষ্ঠাগুলিতে লিগ্যাসি কোড নিয়ে কাজ করার সময় বিশেষত সহায়ক ছিল। সাম্প্রতিককালে, গৃহীত ভাল অনুশীলন হ'ল পদ্ধতিগুলি ছোট রাখা যা একাধিক প্রস্থানকে বোঝার প্রতিবন্ধকতা তৈরি করে। নীচের ক্রোনোজ উদাহরণটি উপরে থেকে অনুলিপি করা হয়েছে, প্রশ্নটি হল // কোডের বাকী ... তে কী ঘটে ?

void string fooBar(string s, int? i) {

  if(string.IsNullOrEmpty(s) || i == null) return null;

  var res = someFunction(s, i);

  foreach(var r in res) {
      if(!r.Passed) return null;
  }

  // Rest of code...

  return ret;
}

আমি বুঝতে পারছি উদাহরণ কিছুটা কল্পিত হয় কিন্তু আমি refactor টানতে হবে foreach একটি LINQ বিবৃতি যে তারপর গার্ড দফা বিবেচনা করা যেতে পারে বা লুপ। আবার, কল্পিত উদাহরণে কোডের অভিপ্রায় স্পষ্ট এবং নয় someFunction () কিছু অন্যান্য পার্শ্ব প্রতিক্রিয়া হয়ে থাকতে পারে বা ফলাফলে ব্যবহার করা যেতে পারে // কোডের বিশ্রাম ...

if (string.IsNullOrEmpty(s) || i == null) return null;
if (someFunction(s, i).Any(r => !r.Passed)) return null;

নিম্নলিখিত রিফ্যাক্টরড ফাংশন প্রদান:

void string fooBar(string s, int? i) {

  if (string.IsNullOrEmpty(s) || i == null) return null;
  if (someFunction(s, i).Any(r => !r.Passed)) return null;

  // Rest of code...

  return ret;
}

সি ++ এর কি ব্যতিক্রম নেই? তারপরে আপনি nullযুক্তিটি গ্রহণযোগ্য নয় বলে ইঙ্গিত দিয়ে ব্যতিক্রম ছুঁড়ে ফিরবেন কেন ?
মার্টেন বোদেউয়েস

1
যেমন আমি ইঙ্গিত করেছি, উদাহরণ কোডটি পূর্ববর্তী উত্তর থেকে অনুলিপি করা হয়েছে ( স্ট্যাকওভারফ্লো . com/ a/ 36729 / 132599 )। আসল উদাহরণটি নালাগুলি ফিরে এসেছিল এবং যুক্তি ব্যতিক্রমগুলি ছুঁড়ে ফেলার জন্য রিফ্যাক্টরিং আমি যে বিন্দুতে চেষ্টা করার চেষ্টা করছিলাম বা মূল প্রশ্নটি বস্তুগত ছিল না। ভাল অনুশীলনের বিষয় হিসাবে, তবে হ্যাঁ আমি সাধারণত (সি # তে) একটি নালিক্য মান ফেরানোর পরিবর্তে গার্ডের একটি ধারাতে একটি আর্গুমেন্টনুল এক্সসেপশন নিক্ষেপ করতাম।
ডেভিড ক্লার্ক 0

7

একটি ভাল কারণ যা আমি ভাবতে পারি তা হল কোড রক্ষণাবেক্ষণ: আপনার একক বহির্গমন রয়েছে। আপনি যদি ফলাফলের ফর্ম্যাটটি পরিবর্তন করতে চান, ..., এটি বাস্তবায়ন করা সহজতর। এছাড়াও, ডিবাগিংয়ের জন্য, আপনি কেবল সেখানে ব্রেকআপপয়েন্টটি আটকে রাখতে পারেন :)

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


এটি আসলে কোনও পার্থক্য করে না। যদি আপনি স্থানীয় ভেরিয়েবলের প্রকারটি পরিবর্তন করে থাকেন তবে আপনাকে সেই স্থানীয় ভেরিয়েবলের সমস্ত অ্যাসাইনমেন্ট ঠিক করতে হবে। এবং যাইহোক যাইহোক আলাদা স্বাক্ষর সহ কোনও পদ্ধতিটি সংজ্ঞায়িত করা আরও ভাল, কারণ আপনাকে সমস্ত পদ্ধতি কলগুলিও ঠিক করতে হবে।
মার্টেন বোদেউয়েস

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

@nnnnnn ঠিক আছে, আপনি যদি আউটপুটে পোস্ট প্রসেসিং করতে চান ... তবে আমি কেবল একটি নতুন পদ্ধতি তৈরি করব যা পোস্ট প্রসেসিং করে এবং পুরানোটিকে একা রেখে দেয়। এটি কেবল রিফ্যাক্টর থেকে সামান্য শক্ত, তবে আপনাকে অন্য কলগুলি যে কোনও উপায়ে নতুন ফর্ম্যাটের সাথে সামঞ্জস্যপূর্ণ কিনা তা পরীক্ষা করতে হবে। তবে এটি কোনও কার্যকর কারণ নয় less
মার্টেন বোদেউয়েস

7

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

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


6

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


আপনার মনের ifকথাটি প্রতিটি পদ্ধতির কলের সামনে বিবৃতিটি এড়াতে বলার অপেক্ষা রাখে না যা সাফল্য ফিরে আসে বা না :(
মার্টেন বোদেউয়েস

6

একক প্রস্থান বিন্যাস - অন্যান্য সমস্ত জিনিস সমান - কোডকে উল্লেখযোগ্যভাবে আরও পঠনযোগ্য করে তোলে। তবে একটি ধরা আছে: জনপ্রিয় নির্মাণ

resulttype res;
if if if...
return res;

একটি জাল, "রেস =" "রিটার্ন" এর চেয়ে বেশি ভাল নয়। এটির একক রিটার্নের বিবৃতি রয়েছে তবে একাধিক পয়েন্ট যেখানে ফাংশনটি আসলে শেষ হয়।

আপনার যদি একাধিক রিটার্ন (বা "রেস =" গুলি) নিয়ে ফাংশন থাকে তবে একক প্রস্থান পয়েন্ট সহ এটি বেশ কয়েকটি ছোট ফাংশনে বিভক্ত হওয়া প্রায়শই ভাল ধারণা।


6

আমার স্বাভাবিক নীতিটি কোনও ফাংশন শেষে কেবলমাত্র একটি রিটার্নের বিবৃতি দেওয়া উচিত যদি না কোডের জটিলতা আরও যোগ করে ব্যাপকভাবে হ্রাস পায়। আসলে, আমি বরং আইফেলের ভক্ত, যা কোনও একমাত্র রিটার্ন বিবৃতি না পেয়ে একমাত্র রিটার্ন বিধি প্রয়োগ করে (আপনার ফলাফলের জন্য কেবল একটি স্বয়ং-নির্মিত 'ফলাফল' পরিবর্তনশীল)।

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


5

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

পার্ল 6: খারাপ উদাহরণ

sub Int_to_String( Int i ){
  given( i ){
    when 0 { return "zero" }
    when 1 { return "one" }
    when 2 { return "two" }
    when 3 { return "three" }
    when 4 { return "four" }
    ...
    default { return undef }
  }
}

ভাল এইভাবে লেখা হবে

পার্ল 6: ভাল উদাহরণ

@Int_to_String = qw{
  zero
  one
  two
  three
  four
  ...
}
sub Int_to_String( Int i ){
  return undef if i < 0;
  return undef unless i < @Int_to_String.length;
  return @Int_to_String[i]
}

দ্রষ্টব্য এটি কেবল একটি দ্রুত উদাহরণ ছিল


ঠিক আছে কেন এটিকে ভোট দেওয়া হয়েছিল? এটি মতামত নয় এমন নয়।
ব্র্যাড গিলবার্ট

5

আমি গাইডলাইন হিসাবে শেষে সিঙ্গল রিটার্নের জন্য ভোট দিই। এটি একটি সাধারণ কোড সাফ আপ হ্যান্ডলিংয়ে সহায়তা করে ... উদাহরণস্বরূপ, নিম্নলিখিত কোডটি একবার দেখুন ...

void ProcessMyFile (char *szFileName)
{
   FILE *fp = NULL;
   char *pbyBuffer = NULL:

   do {

      fp = fopen (szFileName, "r");

      if (NULL == fp) {

         break;
      }

      pbyBuffer = malloc (__SOME__SIZE___);

      if (NULL == pbyBuffer) {

         break;
      }

      /*** Do some processing with file ***/

   } while (0);

   if (pbyBuffer) {

      free (pbyBuffer);
   }

   if (fp) {

      fclose (fp);
   }
}

আপনি সি কোডে একক ফেরতের পক্ষে ভোট দিন। তবে আপনি যদি এমন কোনও ভাষায় কোডিং করে যা আবর্জনা সংগ্রহ এবং চেষ্টা করে..ফিনালি ব্লক করে থাকেন?
অ্যান্থনি

4

এটি সম্ভবত একটি অস্বাভাবিক দৃষ্টিভঙ্গি, তবে আমি মনে করি যে যে কেউ বিশ্বাস করে যে একাধিক রিটার্নের স্টেটমেন্ট গ্রহণ করা উচিত তাকে কখনও কোনও মাইক্রোপ্রসেসরে ডিবাগার ব্যবহার করতে হয়নি যা কেবলমাত্র 4 টি হার্ডওয়্যার ব্রেকপয়েন্টগুলিকে সমর্থন করে। ;-)

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


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

আপনার ডিবাগারের উপরও নির্ভর করে।
মার্টেন বোদেউয়েস

4

কোনও ফাংশনে আপনার যত বেশি রিটার্ন স্টেটমেন্ট রয়েছে, সেই এক পদ্ধতিতে জটিলতা তত বেশি। যদি আপনি নিজেকে ভাবছেন যে যদি আপনার কাছে অনেকগুলি রিটার্নের বিবৃতি রয়েছে তবে আপনি নিজেকে জিজ্ঞাসা করতে চাইতে পারেন যে সেই ফাংশনে আপনার অনেক বেশি কোডের লাইন আছে কিনা।

তবে, না, এক / বহু রিটার্ন বিবৃতিতে কোনও ভুল নেই। কিছু ভাষায়, এটি অন্যদের (সি) এর চেয়ে ভাল অনুশীলন (সি ++)।

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