বিবরণটি রিটার্ন সহ স্যুইচ করুন - কোডের সঠিকতা


91

ধরা যাক আমার প্রায় সি কাঠামোয় এই কাঠামোর কোড রয়েছে:

switch (something)
{
    case 0:
      return "blah";
      break;

    case 1:
    case 4:
      return "foo";
      break;

    case 2:
    case 3:
      return "bar";
      break;

    default:
      return "foobar";
      break;
}

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

আপনি কি মনে করেন? এগুলি অপসারণ করা কি ঠিক আছে? না আপনি তাদের "বোধগম্যতা" বৃদ্ধির জন্য রাখবেন?

উত্তর:


139

breakবিবৃতি সরান । এগুলির দরকার নেই এবং সম্ভবত কিছু সংকলক "অ্যাক্সেসযোগ্য কোড" সতর্কতা জারি করবেন।


4
একই হিসাবে অন্যান্য শর্তাধীন নিয়ন্ত্রণ-জাম্পিং বিবৃতিগুলির সাথে প্রযোজ্য, continueবা goto- এর স্থানে সেগুলি ব্যবহার করা বুদ্ধিমানের কাজ break
ক্যাফে

32

আমি পুরোপুরি একটি আলাদা ট্যাক্স নিতে হবে। পদ্ধতি / ফাংশনের মাঝখানে ফিরে আসবেন না। পরিবর্তে, কেবল স্থানীয় ভেরিয়েবলে রিটার্ন মানটি রেখে শেষে প্রেরণ করুন।

ব্যক্তিগতভাবে, আমি নিম্নলিখিতটি আরও পঠনযোগ্য বলে মনে করি:

String result = "";

switch (something) {
case 0:
  result = "blah";
  break;
case 1:
  result = "foo";
  break;
}

return result;

24
"ওয়ান প্রস্থান" দর্শনটি সিতে উপলব্ধি করে, যেখানে আপনার জিনিসগুলি সঠিকভাবে পরিষ্কার করা দরকার ensure সি ++ এ বিবেচনা করে কোনও ব্যতিক্রম আপনাকে ফাংশন থেকে বের করে দেওয়া যেতে পারে, এক প্রস্থান দর্শনটি সি ++ এ আসলেই কার্যকর নয়।
বিলি ওনিল

29
তত্ত্বগতভাবে এটি দুর্দান্ত ধারণা, তবে এটির জন্য প্রায়শই অতিরিক্ত নিয়ন্ত্রণ ব্লকগুলির প্রয়োজন হয় যা পাঠযোগ্যতা বাধাগ্রস্ত করতে পারে।
মিকেরোবি

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

7
ঠিক আছে, এবং কোডের মাঝখানে ফিরে আসা ব্লকগুলি আমাকে GOTO অপব্যবহারের স্মরণ করিয়ে দেয়।
নোটমে

4
@ ক্রিস: দীর্ঘতর কার্যক্রমে আমি পুরোপুরি একমত - তবে এটি সাধারণত বড় সমস্যার মুখোমুখি হয়, সুতরাং এটি পুনরুদ্ধার করুন। অনেক ক্ষেত্রে এটি একটি তুচ্ছ ফাংশনটি একটি স্যুইচটিতে ফিরে আসে এবং এটি যা ঘটবে তা খুব স্পষ্ট, সুতরাং অতিরিক্ত পরিবর্তনশীল ট্র্যাকিংয়ের ক্ষেত্রে মস্তিষ্কের শক্তি অপচয় করবেন না।
স্টিফেন

8

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

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

একটি ব্যতিক্রম: কোনও ফাংশনের শুরুতে কোনও খারাপ পরামিতি সনাক্ত করা হলে - প্রথম দিকে ফিরে আসা ঠিক আছে - কোনও সংস্থান অর্জনের আগে।


এই বিশেষের জন্য ভাল হতে পারে switch, তবে সাধারণভাবে অগত্যা সেরা নয়। ঠিক আছে, একটি ফাংশনের অভ্যন্তরে স্যুইচ স্টেটমেন্টটি আরও 500 টি লাইন কোডের আগে বলে যা কিছু নির্দিষ্ট ক্ষেত্রে থাকলে বৈধ থাকে true। যে সমস্ত ক্ষেত্রে এটি কার্যকর করার প্রয়োজন হয় না তার জন্য সমস্ত অতিরিক্ত কোড কার্যকর করার কী দরকার; those জনের জন্য কেবল returnভিতরে থাকা ভাল না ? switchcase
Fr0zenFyr

6

বিরতি রাখুন - বিরতি ইতিমধ্যে স্থানে থাকলে যদি আপনি পরে কোড সম্পাদনা করেন তবে / আপনি সমস্যার মধ্যে পড়ার সম্ভাবনা কম।

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


5

এগুলো মুছে ফেলো. caseবিবৃতি থেকে ফিরে আসার মত বুদ্ধিদীপ্ত এবং অন্যথায় এটি "অ্যাক্সেসযোগ্য কোড" শোরগোল।


5

আমি তাদের অপসারণ করা হবে। আমার বইতে, এর মতো ডেড কোডটিকে ত্রুটি হিসাবে বিবেচনা করা উচিত কারণ এটি আপনাকে দ্বিগুণ গ্রহণ করে এবং নিজেকে জিজ্ঞাসা করে "আমি কখনই এই লাইনটি কার্যকর করব?"


4

আমি সাধারণত এগুলি ছাড়া কোডটি লিখতাম। আইএমও, ডেড কোডটি opালুতা এবং / বা বোঝার অভাব নির্দেশ করে।

অবশ্যই, আমি এই জাতীয় কিছু বিবেচনা করব:

char const *rets[] = {"blah", "foo", "bar"};

return rets[something];

সম্পাদনা: সম্পাদিত পোস্ট সহ, এই সাধারণ ধারণাটি ভাল কাজ করতে পারে:

char const *rets[] = { "blah", "foo", "bar", "bar", "foo"};

if ((unsigned)something < 5)
    return rets[something]
return "foobar";

কিছু সময়ে, বিশেষত যদি ইনপুট মানগুলি খুব কম হয় (উদাহরণস্বরূপ, 1, 100, 1000 এবং 10000), আপনি পরিবর্তে একটি বিচ্ছিন্ন অ্যারে চান। আপনি এটি প্রয়োগ করতে পারেন গাছ বা মানচিত্র হিসাবে যুক্তিসঙ্গতভাবে ভাল (যদিও, অবশ্যই, একটি স্যুইচ এখনও এই ক্ষেত্রে কাজ করে)।


কেন এই সমাধানটি ভাল কাজ করে না তা প্রতিফলিত করার জন্য পোস্ট সম্পাদনা করেছেন।
houbysoft

@ আপনার সম্পাদনা: হ্যাঁ, তবে এটি আরও বেশি স্মৃতি গ্রহণ করবে, ইত্যাদি IM
houbysoft

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

সত্য। আমি এখনও আমার সমাধানটিতে আটকে থাকব যদিও মানগুলির তালিকা খুব দীর্ঘ, এবং একটি স্যুইচটি আরও ভাল মনে হয়।
houbysoft

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

2

আমি তাদের অপসারণ এবং একটি ডিফল্ট সংজ্ঞায়িত বলতে হবে: শাখা।


যদি কোনও বুদ্ধিমান ডিফল্ট না থাকে তবে আপনার ডিফল্ট সংজ্ঞা দেওয়া উচিত নয়।
বিলি ওনিল

একটি আছে, এবং আমি একটি সংজ্ঞায়িত করেছি, আমি এখনই এটি প্রশ্নের মধ্যে রাখি না, এটি এখন সম্পাদনা করেছি।
houbysoft

2

সাথে অ্যারে রাখা ভাল না

arr[0] = "blah"
arr[1] = "foo"
arr[2] = "bar"

এবং করব return arr[something];?

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


কেন এই সমাধানটি ভাল কাজ করে না তা প্রতিফলিত করার জন্য পোস্ট সম্পাদনা করেছেন।
houbysoft

2

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


2

আপনি কি মনে করেন? এগুলি অপসারণ করা কি ঠিক আছে? না আপনি তাদের "বোধগম্যতা" বৃদ্ধির জন্য রাখবেন?

এগুলি অপসারণ করা ভাল is ব্যবহার return হয় ঠিক দৃশ্যকল্প যেখানে breakব্যবহার করা উচিত নয়।


1

মজাদার. এই উত্তরগুলির বেশিরভাগের Theক্যমত্য থেকে মনে হয় যে অপ্রয়োজনীয় breakবিবৃতি অপ্রয়োজনীয় বিশৃঙ্খলা। অন্যদিকে, আমি breakএকটি স্যুইচে স্টেটমেন্টটি কেসের 'সমাপ্তি' হিসাবে পড়েছি । caseযেগুলি ব্লকগুলি শেষ হয় না সেগুলি breakবাগের পরেও সম্ভাব্য পতন হিসাবে আমার দিকে ঝাঁপিয়ে পড়ে।

আমি জানি যে এটির returnপরিবর্তে যখন কোনও পরিবর্তিত হয় তখন তা হয় না breakতবে আমার চোখগুলি এইভাবে একটি 'স্যুইচ'-এ কেস ব্লক করে, তাই আমি ব্যক্তিগতভাবে পছন্দ করি যে প্রতিটিকে caseএকটি করে যুক্ত করা যায় break। তবে অনেক সংকলক অপ্রতিরোধ্য / অপ্রয়োজনীয় হওয়ার breakপরে অভিযোগ করেন returnএবং দৃশ্যত আমি যেভাবেই সংখ্যালঘুতে আছি বলে মনে হয়।

সুতরাং breakনিম্নলিখিত একটি পরিত্রাণ পেতে return

নোট: একক প্রবেশ / প্রস্থান বিধি লঙ্ঘন করা ভাল ধারণা কিনা তা এই সমস্তগুলি এড়ানো হচ্ছে। যতদূর যায়, আমার একটি মতামত আছে যে দুর্ভাগ্যক্রমে পরিস্থিতির উপর নির্ভর করে পরিবর্তিত হয় ...


0

আমি বলছি এগুলি সরান। যদি আপনার কোডটি অপঠনযোগ্য হয় তবে আপনাকে 'নিরাপদ দিকে থাকতে' সেখানে বিরতি আটকে রাখা দরকার, আপনার কোডিং শৈলীতে পুনর্বিবেচনা করা উচিত :)

এছাড়াও আমি সবসময় সুইচ স্টেটমেন্টে ব্রেক এবং রিটার্ন মিশ্রিত না করাকে পছন্দ করেছি, বরং তাদের মধ্যে একটির সাথে লেগেছি।


0

আমি ব্যক্তিগতভাবে breakএস হারাতে থাকে । সম্ভবত এই অভ্যাসের একটি উত্স হ'ল উইন্ডোজ অ্যাপ্লিকেশনগুলির জন্য প্রোগ্রামিং উইন্ডো প্রক্রিয়া:

LRESULT WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_SIZE:
            return sizeHandler (...);
        case WM_DESTROY:
            return destroyHandler (...);
        ...
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

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


0

আমি মনে করি * বিরতি * গুলি একটি উদ্দেশ্যে রয়েছে। এটি প্রোগ্রামিংয়ের 'আদর্শ' বাঁচিয়ে রাখা। যদি আমাদের যৌক্তিক সংগতি ছাড়াই আমাদের কোডটি 'প্রোগ্রাম' করা হয় তবে এটি সম্ভবত আপনার কাছে এখন পঠনযোগ্য, তবে আগামীকাল চেষ্টা করুন। এটি আপনার বসকে বোঝানোর চেষ্টা করুন। এটি উইন্ডোজ 3030 এ চালানোর চেষ্টা করুন।

ব্লিঃ, ধারণাটি খুব সহজ:


Switch ( Algorithm )
{

 case 1:
 {
   Call_911;
   Jump;
 }**break**;
 case 2:
 {
   Call Samantha_28;
   Forget;
 }**break**;
 case 3:
 {
   Call it_a_day;
 }**break**;

Return thinkAboutIt?1:return 0;

void Samantha_28(int oBed)
{
   LONG way_from_right;
   SHORT Forget_is_my_job;
   LONG JMP_is_for_assembly;
   LONG assembly_I_work_for_cops;

   BOOL allOfTheAbove;

   int Elligence_says_anyways_thinkAboutIt_**break**_if_we_code_like_this_we_d_be_monkeys;

}
// Sometimes Programming is supposed to convey the meaning and the essence of the task at hand. It is // there to serve a purpose and to keep it alive. While you are not looking, your program is doing  // its thing. Do you trust it?
// This is how you can...
// ----------
// **Break**; Please, take a **Break**;

/ * যদিও একটি ছোটখাটো প্রশ্ন। উপরেরটি পড়ার সময় আপনি কতটা কফি পেয়েছিলেন? আইটি সিস্টেমকে কখনও কখনও ভেঙে দেয় * /


0

এক পর্যায়ে কোড প্রস্থান করুন। এটি কোডে আরও ভাল পাঠযোগ্যতা সরবরাহ করে। এর মধ্যে রিটার্ন স্টেটমেন্ট (একাধিক প্রস্থান) যুক্ত করা ডিবাগিংকে শক্ত করে তুলবে।


0

আপনার যদি "অনুসন্ধান" প্রকারের কোড থাকে তবে আপনি নিজেই কোনও পদ্ধতিতে স্যুইচ-কেস ধারাটি প্যাকেজ করতে পারেন।

আমি মজাদার জন্য বিকাশ করছি এমন একটি "শখ" সিস্টেমে এর কয়েকটি রয়েছে:

private int basePerCapitaIncomeRaw(int tl) {
    switch (tl) {
        case 0:     return 7500;
        case 1:     return 7800;
        case 2:     return 8100;
        case 3:     return 8400;
        case 4:     return 9600;
        case 5:     return 13000;
        case 6:     return 19000;
        case 7:     return 25000;
        case 8:     return 31000;
        case 9:     return 43000;
        case 10:    return 67000;
        case 11:    return 97000;
        default:    return 130000;
    }
}

(হ্যাঁ, এটিই জিআরপিএস স্পেস ...)

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

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

(তৃতীয় ... হাতে ... আপনি সর্বদা তার নিজস্ব পদ্ধতিতে একটি স্যুইচ রিফেক্টর করতে পারেন ... আমি সন্দেহ করি যে এটির কার্যকারিতার উপর প্রভাব ফেলবে, এবং আধুনিক সংকলকরা এমনকি এটি স্বীকৃতি দিতে পারলে আমার অবাক করা হত না) অন্তর্নিহিত হতে পারে এমন কিছু ...)

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