“එක නැවත පැමිණීම” යන සංකල්පය පැමිණියේ කොහෙන්ද?


1078

මම බොහෝ විට කතා කරන්නේ " එකම ක්‍රමයට බහුවිධ ප්‍රතිලාභ ප්‍රකාශ නොකරන්න " යනුවෙන් පවසන ක්‍රමලේඛකයින් සමඟය. එයට හේතු මට කියන්නැයි මම ඔවුන්ගෙන් ඉල්ලා සිටින විට, මට ලැබෙන්නේ " කේතීකරණ ප්‍රමිතිය එසේ පවසයි. " හෝ " එය අවුල් සහගතය. " තනි ප්‍රතිලාභ ප්‍රකාශයකින් ඔවුන් මට විසඳුම් පෙන්වන විට, කේතය මට කැතයි. උදාහරණයක් වශයෙන්:

if (condition)
   return 42;
else
   return 97;

" මෙය කැතයි, ඔබ දේශීය විචල්යයක් භාවිතා කළ යුතුයි! "

int result;
if (condition)
   result = 42;
else
   result = 97;
return result;

මෙම 50% කේත පිපිරීම මඟින් වැඩසටහන තේරුම් ගැනීමට පහසු වන්නේ කෙසේද? පුද්ගලිකව, මට එය දුෂ්කර යැයි හැඟේ, මන්ද යත් රාජ්‍ය අවකාශය වෙනත් විචල්‍යයකින් වැඩි වී ඇති බැවින් පහසුවෙන් වළක්වා ගත හැකි බැවිනි.

ඇත්ත වශයෙන්ම, සාමාන්‍යයෙන් මම ලියන්නේ:

return (condition) ? 42 : 97;

නමුත් බොහෝ ක්‍රමලේඛකයින් කොන්දේසි සහිත ක්‍රියාකරු අතහැර දමා දිගු ආකෘතියට වැඩි කැමැත්තක් දක්වයි.

“එක් ප්‍රතිලාභයක් පමණක්” යන මෙම අදහස පැමිණියේ කොහෙන්ද? මෙම සමුළුව ඇතිවීමට historical තිහාසික හේතුවක් තිබේද?


3
මෙය ආරක්ෂක වගන්ති ප්‍රතිනිර්මාණයට තරමක් සම්බන්ධ වේ. stackoverflow.com/a/8493256/679340 ආරක්ෂක වගන්තිය ඔබේ ක්‍රමවල ආරම්භයට ප්‍රතිලාභ එක් කරයි. එය මගේ මතය අනුව කේතය බොහෝ පිරිසිදු කරයි.
පියොටර් පෙරක්

4
එය පැමිණියේ ව්‍යුහාත්මක ක්‍රමලේඛනය යන සංකල්පයෙන් ය. නැවත පැමිණීමට පෙර යමක් කිරීමට හෝ පහසුවෙන් නිදොස්කරණය කිරීමට කේතය පහසුවෙන් වෙනස් කිරීමට ඔබට හැකි බව සමහරු තර්ක කළ හැකිය.
martinkunev

4
මම හිතන්නේ උදාහරණය එක් ආකාරයකින් හෝ වෙනත් ආකාරයකින් ශක්තිමත් මතයක් නොතිබූ සරල සරල අවස්ථාවකි. ආපසු පැමිණීමේ ප්‍රකාශ 15 ක් සහ නැවත නොපැමිණෙන තවත් ශාඛා දෙකක් වැනි පිස්සු තත්වයන්ගෙන් අපව මඟ පෙන්වීම සඳහා තනි පිවිසුම්-තනි-පිටවීමේ පරමාදර්ශය වැඩිය!
මෙන්ඩෝටා

2
එය මා මෙතෙක් කියවා ඇති නරකම ලිපි වලින් එකකි. ඕනෑම දෙයක් සාක්ෂාත් කරගන්නේ කෙසේදැයි සොයා ගැනීමට වඩා කතුවරයා තම OOP හි පාරිශුද්ධ භාවය ගැන මන as කල්පිත ලෙස වැඩි කාලයක් ගත කරන බවක් පෙනේ. ප්‍රකාශන සහ ඇගයීමේ ගස්වල වටිනාකමක් ඇති නමුත් ඔබට සාමාන්‍ය ශ්‍රිතයක් ලිවිය හැකි විට නොවේ.
DeadMG

4
ඔබ තත්වය සම්පූර්ණයෙන්ම ඉවත් කළ යුතුය. පිළිතුර 42 යි.
කැම්බන්චියස්

Answers:


1150

බොහෝ වැඩසටහන් එකලස් කිරීමේ භාෂාවෙන්, ෆෝට්‍රාන් හෝ කෝබෝල් වලින් කරන විට “තනි ප්‍රවේශය, තනි පිටවීම” ලියා ඇත. නූතන භාෂාවන් ඩිජ්ක්ස්ට්‍රා අනතුරු ඇඟවූ පිළිවෙත් වලට සහාය නොදක්වන හෙයින් එය බොහෝ දුරට වැරදි ලෙස අර්ථකථනය කර ඇත.

“තනි ප්‍රවේශය” යන්නෙහි තේරුම “කාර්යයන් සඳහා විකල්ප ප්‍රවේශ ස්ථාන නිර්මාණය නොකරන්න” යන්නයි. එකලස් කිරීමේ භාෂාවෙන්, ඇත්ත වශයෙන්ම, ඕනෑම උපදෙස් අනුව ශ්‍රිතයක් ඇතුළත් කළ හැකිය. ENTRYප්‍රකාශය සමඟ කාර්යයන් සඳහා ෆෝට්‍රාන් බහු ප්‍රවේශයන් සඳහා සහාය විය :

      SUBROUTINE S(X, Y)
      R = SQRT(X*X + Y*Y)
C ALTERNATE ENTRY USED WHEN R IS ALREADY KNOWN
      ENTRY S2(R)
      ...
      RETURN
      END

C USAGE
      CALL S(3,4)
C ALTERNATE USAGE
      CALL S2(5)

“තනි පිටවීම” යන්නෙන් අදහස් කරන්නේ ශ්‍රිතයක් නැවත එක් ස්ථානයකට පමණක් පැමිණිය යුතු බවයි : ඇමතුමෙන් පසුව ප්‍රකාශය. එය කළේ නැහැ උත්සවයකට පමණක් නැවත යුතු බව මින් අදහස් සිට එක් එක් ස්ථානය. විට ව්යුහයට ක්රමලේඛ ලියා නැත, එය විකල්ප ස්ථානයක නැවත මගින් වරදක් දැක්වීමට උත්සවයකට සඳහා සාමාන්ය සිරිතකි විය. ෆෝට්‍රාන් මේ සඳහා "විකල්ප ප්‍රතිලාභ" හරහා සහාය විය:

C SUBROUTINE WITH ALTERNATE RETURN.  THE '*' IS A PLACE HOLDER FOR THE ERROR RETURN
      SUBROUTINE QSOLVE(A, B, C, X1, X2, *)
      DISCR = B*B - 4*A*C
C NO SOLUTIONS, RETURN TO ERROR HANDLING LOCATION
      IF DISCR .LT. 0 RETURN 1
      SD = SQRT(DISCR)
      DENOM = 2*A
      X1 = (-B + SD) / DENOM
      X2 = (-B - SD) / DENOM
      RETURN
      END

C USE OF ALTERNATE RETURN
      CALL QSOLVE(1, 0, 1, X1, X2, *99)
C SOLUTION FOUND
      ...
C QSOLVE RETURNS HERE IF NO SOLUTIONS
99    PRINT 'NO SOLUTIONS'

මෙම ක්‍රම දෙකම අතිශයින්ම දෝෂ සහිත විය. විකල්ප ඇතුළත් කිරීම් භාවිතා කිරීම බොහෝ විට සමහර විචල්‍යයන් ආරම්භ නොකෙරේ. විකල්ප ප්‍රතිලාභ භාවිතා කිරීම GOTO ප්‍රකාශයක සියලු ගැටලු ඇති අතර, ශාඛා තත්ත්වය ශාඛාවට යාබදව නොව, සබ්ට්‍රවුටින්හි කොතැනක හෝ ඇති බවට අමතර සංකූලතාවයක් ඇති විය.


44
ස්පැගටි කේතය අමතක කරන්න එපා . නැවත පැමිණීම වෙනුවට GOTO භාවිතා කරමින් උපසිරැසි වලින් පිටවීම නොදන්නා අතර, ක්‍රියාකාරී ඇමතුම් පරාමිතීන් සහ ආපසු ලිපිනය තොගයේ තබා ඇත. තනි පිටවීම ප්‍රවර්ධනය කරන ලද්දේ අවම වශයෙන් සියලු කේත මාර්ග නැවත පැමිණීමේ ප්‍රකාශයකට යොමු කිරීමේ ක්‍රමයක් ලෙස ය.
ටීඑම්එන්

3
@TMN: මුල් දිනවල බොහෝ යන්ත්‍රවල දෘඩාංග තොගයක් නොතිබුණි. පුනරාවර්තනය සාමාන්‍යයෙන් සහාය නොදක්වයි. සබ්ට්‍රවුටින් තර්ක හා ආපසු ලිපිනය සබ්ට්‍රෝටීන් කේතයට යාබදව ස්ථාවර ස්ථානවල ගබඩා කර ඇත. නැවත පැමිණීම වක්‍ර ගොටෝ එකක් පමණි.
kevin cline

6
ඇකේවින්: ඔව්, නමුත් ඔබට අනුව මෙය නව නිපැයුමක් ලෙස තවදුරටත් අදහස් නොවේ. (BTW, මම ඇත්තටම සාධාරණ වග ෆ්රෙඩ් සඳහා මනාප විය ඇසූ ඉන්නේ වත්මන් එසේම, සී වී ඇත "තනි පිටවීමේ" පිළිබඳ අර්ථ නිරූපණය පැමිණෙන්නේ.) constමෙහි භාවිතා කරන්නන් බොහෝ ඉපදෙන්නත් කලින් සිට, ඒ නිසා තවදුරටත් අගනුවර ෙඤෙය කිසිදු අවශ්යතාවයක් සී හි පවා. නමුත් ජාවා එම නරක පැරණි සී පුරුදු සියල්ලම ආරක්ෂා කළේය.
sbi

4
එසේ නම්, ව්‍යතිරේකයන් තනි පිටවීම පිළිබඳ මෙම අර්ථ නිරූපණය උල්ලං do නය කරනවාද? (නැතහොත් ඔවුන්ගේ වඩාත් ප්‍රාථමික ous ාති සහෝදරයාද setjmp/longjmp?)
මේසන් වීලර්

3
තනි ප්‍රතිලාභ පිළිබඳ වර්තමාන අර්ථ නිරූපණය ගැන දෘෂ්ටි කෝණයෙන් විමසුවද, මෙම පිළිතුර වඩාත් historical තිහාසික මූලයන් ඇති පිළිතුරයි. ඔබේ භාෂාව VB (.NET නොවේ) හි විශ්මය ජනකතාවයට ගැලපෙන පරිදි මිස, රීතියක් ලෙස තනි ප්‍රතිලාභයක් භාවිතා කිරීමේ තේරුමක් නැත. කෙටි පරිපථ නොවන බූලියන් තර්කනය භාවිතා කිරීමට මතක තබා ගන්න.
acelent

922

තනි ප්‍රවේශය, තනි පිටවීම (SESE) පිළිබඳ මෙම අදහස පැමිණෙන්නේ සී සහ එකලස් කිරීම වැනි පැහැදිලි සම්පත් කළමනාකරණය සහිත භාෂාවලින් ය . C හි, මෙවැනි කේත මඟින් සම්පත් කාන්දු වේ:

void f()
{
  resource res = acquire_resource();  // think malloc()
  if( f1(res) )
    return; // leaks res
  f2(res);
  release_resource(res);  // think free()
}

එවැනි භාෂාවලින්, ඔබට මූලික වශයෙන් විකල්ප තුනක් ඇත:

  • පිරිසිදු කිරීමේ කේතය අනුකරණය කරන්න.
    අහ්. අතිරික්තය සෑම විටම නරක ය.

  • gotoපිරිසිදු කිරීමේ කේතයට පනින්න a භාවිතා කරන්න .
    මේ සඳහා පිරිසිදු කිරීමේ කේතය ශ්‍රිතයේ අවසාන දෙය විය යුතුය. (මේ නිසා සමහරු තර්ක කරන්නේ gotoඑයට තැනක් ඇති බවය. ඇත්තෙන්ම එය සී.

  • දේශීය විචල්‍යයක් හඳුන්වා දී ඒ හරහා පාලන ප්‍රවාහය හසුරුවන්න.
    අවාසිය කාරක රීති මගින් හසුරුවනු පාලනය ගලා (හිතන්නේ break, return, if, while) (ඔබ ඇල්ගොරිතමය දෙස බලන කල එම විචල්ය කිසිදු රාජ්ය නිසා) විචල්ය රාජ්ය හරහා මෙහෙයවනවා පාලනය ගලා වඩා අනුගමනය කිරීමට වඩාත් පහසු වේ.

එකලස් කිරීමේදී එය ඊටත් වඩා වෙහෙසකරය, මන්ද ඔබ එම ශ්‍රිතය අමතන විට ශ්‍රිතයක ඕනෑම ලිපිනයකට පනින්නට පුළුවන, එයින් අදහස් කරන්නේ ඔබට ඕනෑම ශ්‍රිතයකට අසීමිත ප්‍රවේශ සංඛ්‍යාවක් ඇති බවයි. (සමහර විට මෙය ප්‍රයෝජනවත් වේ. C ++ හි බහු උරුම අවස්ථා වලදී thisඇමතුම් virtualකාර්යයන් සඳහා අවශ්‍ය දර්ශක ගැලපුම ක්‍රියාත්මක කිරීම සඳහා සම්පාදකයින්ට පොදු ක්‍රමවේදයකි .

ඔබට සම්පත් අතින් කළමණාකරනය කිරීමට සිදු වූ විට, ඕනෑම තැනක ශ්‍රිතයකට ඇතුළු වීමේ හෝ පිටවීමේ විකල්පයන් ගසාකෑම වඩාත් සංකීර්ණ කේතයකට තුඩු දෙන අතර එමඟින් දෝෂ ඇති වේ. එමනිසා, පිරිසිදු කේත සහ අඩු දෝෂ ලබා ගැනීම සඳහා SESE ප්‍රචාරය කරන ලද චින්තනයක් ඇති විය.


කෙසේ වෙතත්, භාෂාවක ව්‍යතිරේකයක් ඇති විට, (පාහේ) ඕනෑම ශ්‍රිතයක් ඕනෑම වේලාවක (පාහේ) අකාලයේ පිටවිය හැකිය, එබැවින් ඔබ කෙසේ හෝ නොමේරූ නැවත පැමිණීම සඳහා ප්‍රතිපාදන සැපයිය යුතුය. (මම සිතන finallyප්රධාන වශයෙන් ජාවා භාවිතා කරන බව හා usingයා මක ( IDisposable, finally; C ++ වෙනුවට සේවක C # දී නැතිව) RAII ඔබ විසින් මෙය සිදු කළ පසු, ඔබ.) නො හැකි නිසා මුල් කිරීමට ඔබ පසු පිරිසිදු කිරීමට අපොහොසත් return, ප්රකාශය ඒ දේ, සමහරවිට SESE ට පක්ෂව ඇති ප්‍රබලම තර්කය අතුරුදහන් වී ඇත.

එමඟින් කියවීමේ හැකියාව ඉතිරි වේ. ඇත්ත වශයෙන්ම, returnප්‍රකාශ දුසිම් භාගයක් සහිත 200 LoC ශ්‍රිතයක් අහඹු ලෙස ඉසිනු ලැබීම හොඳ ක්‍රමලේඛ ශෛලියක් නොවන අතර කියවිය හැකි කේතයක් සෑදෙන්නේ නැත. නමුත් එවැනි ක්‍රියාකාරීත්වයක් නොමේරූ ප්‍රතිලාභ නොමැතිව තේරුම් ගැනීම පහසු නොවනු ඇත.

සම්පත් අතින් හෝ කළමනාකරණය නොකළ යුතු භාෂාවල, පැරණි SESE සම්මුතියට අනුගත වීමේ වටිනාකමක් හෝ වටිනාකමක් නැත. OTOH, මා ඉහත තර්ක කළ පරිදි, SESE බොහෝ විට කේතය වඩාත් සංකීර්ණ කරයි. (සී හැර) වර්තමාන බොහෝ භාෂාවලට නොගැලපෙන ඩයිනෝසෝරයෙකි. කේතයේ අවබෝධය සඳහා උදව් කරනවා වෙනුවට එය එයට බාධා කරයි.


ජාවා ක්‍රමලේඛකයින් මෙයට ඇලී සිටින්නේ ඇයි? මම නොදනිමි, නමුත් මගේ (පිටත) POV වෙතින්, ජාවා සී වෙතින් සම්මුතීන් රාශියක් ගෙන (ඒවා අර්ථවත් වන තැන) සහ ඒවා එහි OO ලෝකයට (ඒවා නිෂ් less ල හෝ සම්පූර්ණයෙන්ම නරක) තැනට යොදන ලදි, එහිදී එය දැන් ඇලී තිබේ ඒවා, කුමන වියදමක් දැරුවත් කමක් නැත. (විෂය පථයේ ආරම්භයේ දී ඔබගේ සියලු විචල්‍යයන් අර්ථ දැක්වීමේ සම්මුතිය මෙන්.)

ක්‍රමලේඛකයින් අතාර්කික හේතූන් මත සියලු ආකාරයේ අමුතු සංකේතවලට ඇලී සිටිති. (ගැඹුරින් කැදැලි කරන ලද ව්‍යුහාත්මක ප්‍රකාශයන් - "ඊතල හෙඩ්ස්" - පැස්කල් වැනි භාෂාවලින් වරෙක ලස්සන කේතයක් ලෙස දැකගත හැකි විය.) මේ සඳහා පිරිසිදු තාර්කික තර්කනයක් යෙදීමෙන් ඔවුන්ගෙන් බහුතරයක් ඔවුන්ගේ ස්ථාපිත මාර්ග වලින් බැහැර වීමට ඒත්තු ගැන්වීමට අපොහොසත් වන බව පෙනේ. එවැනි පුරුදු වෙනස් කිරීමට ඇති හොඳම ක්‍රමය බොහෝ විට සාම්ප්‍රදායික දේ නොව හොඳම දේ කිරීමට ඔවුන්ට ඉක්මනින් ඉගැන්වීමයි. ක්‍රමලේඛන ගුරුවරයෙකු වන ඔබ එය ඔබගේ අතේ තබා ගන්න.:)


54
හරි. ජාවා හි, පිරිසිදු කිරීමේ කේතය අයත් වන්නේ finallyමුල් returnහෝ ව්‍යතිරේක නොසලකා එය ක්‍රියාත්මක වන වගන්තිවල ය .
dan04

15
Java 7 හි ජාවා 7 හි ඔබට finallyවැඩි කාලයක් අවශ්‍ය නොවේ .
ආර්. මාටින්හෝ ෆර්නැන්ඩස්

99
ස්ටීවන්: ඇත්ත වශයෙන්ම ඔබට එය නිරූපණය කළ හැකිය! ඇත්ත වශයෙන්ම, ඔබට ඕනෑම අංගයක් සමඟ සංකෝචිත හා සංකීර්ණ කේත පෙන්විය හැකි අතර එය කේතය සරල හා තේරුම් ගැනීමට පහසු කරවයි. සෑම දෙයක්ම අපයෝජනය කළ හැකිය. කාරණය වන්නේ කේතය ලිවීම පහසු වන පරිදි තේරුම් ගැනීමයි , ඒ සඳහා SESE කවුළුවෙන් ඉවතට විසි කිරීම සම්බන්ධ වන විට එය එසේ විය යුතු අතර විවිධ භාෂාවන්ට අදාළ පැරණි පුරුදු විනාශ කරන්න. නමුත් කේතය කියවීම පහසු කරයි කියා මා සිතන්නේ නම් විචල්‍යයන් මඟින් ක්‍රියාත්මක කිරීම පාලනය කිරීමට මම පසුබට නොවෙමි. දශක දෙකකට ආසන්න කාලයක් තුළ එවැනි කේතයක් දැක ඇති බව මට මතක නැත.
sbi

21
Ar කාල්: ඇත්ත වශයෙන්ම, ජාවා වැනි ජීසී භාෂාවන්ගේ දැඩි අඩුපාඩුවක් වන්නේ එක් සම්පතක් පිරිසිදු කිරීමෙන් ඔවුන් ඔබව නිදහස් කිරීමයි, නමුත් අනෙක් සියල්ල සමඟ අසමත් වීමයි. (C ++ භාවිතා කරන සියලුම සම්පත් සඳහා මෙම ගැටලුව දිඟේ RAII .) නමුත් මම (මම පමණක් ය පමණක් මතකය කතා නැත malloc()හා free()උදාහරණයක් ලෙස අදහස් බවට), මම, පොදුවේ සම්පත් ගැන කතා කරන ලදී. GC විසින් මෙම ගැටළු විසඳනු ඇතැයි මම ඇඟවූයේ නැත. (මම G ++ කොටුවෙන් පිටත නොමැති C ++ ගැන සඳහන් කළෙමි.) මට තේරෙන පරිදි, ජාවා finallyහි මෙම ගැටළුව විසඳීම සඳහා භාවිතා වේ.
sbi

11
bsbi: කාර්යයක් සඳහා (ක්‍රියා පටිපාටිය, ක්‍රමවේදය යනාදිය) වඩා වැදගත් වන්නේ පිටුවකට වඩා දිගු නොවීම වඩා පැහැදිලිව අර්ථ දක්වා ඇති කොන්ත්‍රාත්තුවක් තිබීමයි; අත්තනෝමතික දිග සීමාවක් සපුරාලීම සඳහා එය කපා ඇති නිසා එය පැහැදිලි දෙයක් නොකරන්නේ නම් එය නරක ය. ක්‍රමලේඛනය යනු එකිනෙකට වෙනස්, සමහර විට ගැටුම්කාරී බලවේගයන් ක්‍රීඩා කිරීමයි.
ඩොනල් ෆෙලෝස්

82

එක් අතකින්, තනි ප්‍රතිලාභ ප්‍රකාශ මඟින් ලොග් වීම පහසු කරයි, එසේම ලොග් වීම මත රඳා පවතින නිදොස්කරණය කිරීමේ ආකාර. මට මතකයි එක අවස්ථාවක ප්‍රතිලාභ අගය මුද්‍රණය කිරීම සඳහා ශ්‍රිතය තනි ප්‍රතිලාභයක් දක්වා අඩු කිරීමට මට සිදු වූ අවස්ථා.

  int function() {
     if (bidi) { print("return 1"); return 1; }
     for (int i = 0; i < n; i++) {
       if (vidi) { print("return 2"); return 2;}
     }
     print("return 3");
     return 3;
  }

අනෙක් අතට, ඔබට මෙය function()එම ඇමතුම් වලට ප්‍රතික්‍රියා කර ප්‍රති .ලය _function()ලොග් කළ හැකිය.


32
එය දෝශ නිරාකරණය පහසු කරන බව මම එකතු කරමි, මන්ද ඔබට ශ්‍රිතයෙන් සියලු පිටවීම් * අල්ලා ගැනීමට එක් කඩඉමක් පමණක් සැකසිය යුතුය. සමහර අයිඩීඊ මඟින් එකම දේ කිරීමට ශ්‍රිතයේ සමීප වරහනට විවේකයක් ලබා දීමට මම ඉඩ දෙමි. (* ඔබ පිටවීම
අමතන්නේ

4
ඒ හා සමාන හේතුවක් නිසා, එක් එක් නැවත පැමිණීමට පෙර ඔබේ නව ක්‍රියාකාරිත්වය ඇතුළත් කළ යුතු නැති නිසා, ශ්‍රිතය දීර් extend කිරීම (එකතු කිරීම) පහසු කරයි. උදාහරණයක් ලෙස ශ්‍රිත ඇමතුමේ ප්‍රති result ලය සමඟ ලොගයක් යාවත්කාලීන කිරීමට ඔබට අවශ්‍ය යැයි පවසන්න.
ජෙෆ් සාහෝල්

65
අවංකවම කිව්වොත්, මම කේතය පවත්වා නම්, මම වෙනුවට සිතට අර්ථ ඇති කියලා _function(), සමග returnසුදුසු ස්ථානවල s, සහ නම් දවටනය function()හැන්ඩ්ල් කුළුණක් දුර්වල ප්රවේශ වීම්, එනම්, එක් කර ඇත වඩා function()සියලු ප්රතිලාභ කිරීමට ගොතන තර්ක සහිත තනි පිටවීමේ ගැලපෙන -පොයින්ට් කරන්න එවිට මට එම ස්ථානයට පෙර අතිරේක ප්‍රකාශයක් ඇතුළත් කළ හැකිය.
ruakh

11
සමහර නිදොස් කිරීම් වලදී (එම්එස්වීඑස්) ඔබට අවසාන වසා දැමීමේ වරහන මත බ්‍රේක්පොයින්ට් තැබිය හැකිය
ඇබික්ස්

6
මුද්‍රණය! = නිදොස්කරණය. එය කිසිසේත් තර්කයක් නොවේ.
පියොටර් පෙරක්

53

"තනි ඇතුළත්, තනි පිටවීමේ" ව්යුහගත ක්රමලේඛ කර්තෘ "වෙත Edsger ඩබ්ලිව් Dijkstra ලිපිය විසින් සාදර වූ, 1970 ගනන්වල විප්ලවය සමග ආරම්භ හානිකර සලකා GOTO ප්රකාශය ". ව්‍යුහාත්මක ක්‍රමලේඛනය පිටුපස ඇති සංකල්ප ඔලේ ජොහාන්-ඩෝල්, එඩ්ජර් ඩබ්ලිව්.

"ගොටෝ ප්‍රකාශය හානිකර යැයි සැලකේ" අද පවා කියවීම අවශ්‍ය වේ. “ව්‍යුහාත්මක ක්‍රමලේඛනය” යල් පැන ගිය නමුත් තවමත් ඉතා ප්‍රති ing ලදායක වන අතර ඕනෑම සංවර්ධකයෙකුගේ “කියවිය යුතු” ලැයිස්තුවේ ඉහළින්ම තිබිය යුතුය. උදා: ස්ටීව් මැකොනල්. (ඩෝල්ගේ කොටස මඟින් සිමියුලා 67 හි පන්තිවල මූලික කරුණු දක්වා ඇති අතර ඒවා C ++ පන්ති සඳහා තාක්ෂණික පදනම වන අතර වස්තු-නැඹුරු වැඩසටහන් සියල්ලම වේ.)


6
මෙම ලිපිය ලියා ඇත්තේ C ට දින කිහිපයකට පෙර GOTO හි අධික ලෙස භාවිතා කරන විටය. ඔවුන් සතුරා නොවේ, නමුත් මෙම පිළිතුර අනිවාර්යයෙන්ම නිවැරදි ය. ශ්‍රිතයක් අවසානයේ නොවන ප්‍රතිලාභ ප්‍රකාශයක් effectively ලදායී ලෙස ගොටෝ වේ.
user606723

32
ක්‍රියා පටිපාටිය, කාර්යයන්, ඇමතුම් තොග යනාදිය පිළිබඳ කිසියම් අදහසක් මග හරිමින් වෙනත් ශ්‍රිතයක අහඹු තැනකටgoto හරියටම ඕනෑම තැනකට යා හැකි දිනවල ද ලිපිය ලියා ඇත goto. මා දන්නා එකම අර්ධ-සුවිශේෂී අවස්ථාව C setjmp/ longjmpවේ, ඒ සඳහා දෙපැත්තෙන්ම සහයෝගය අවශ්‍ය වේ. .
cHao

5
"ගොටෝ ප්‍රකාශය හානිකර යැයි සැලකෙන" අවසාන ඡේදයේ සිට: "[2] ගයිසෙප් ජාකොපිනි ප්‍රකාශය වෙත යාමේ (තාර්කික) අතිරික්ත බව ඔප්පු කර ඇති බව පෙනේ. අත්තනෝමතික ප්‍රවාහ රූප සටහනක් වැඩි වශයෙන් හෝ අඩු වශයෙන් යාන්ත්‍රිකව පැනීමකට පරිවර්තනය කිරීමේ අභ්‍යාසය කෙසේ වෙතත්, අඩු එකක් නිර්දේශ කළ යුතු නොවේ . එවිට එහි
ප්‍රති flow ලයක්

10
ප්‍රශ්නයට මෙය සම්බන්ධ වන්නේ කුමක් ද? ඔව්, ඩිජ්ක්ස්ට්‍රාගේ වැඩ අවසානයේදී SESE භාෂාවලට මඟ පෑදූ අතර, එසේ නම් කුමක් ද? බබාගේ වැඩත් එහෙමයි. ශ්‍රිතයක් තුළ පිටවීමේ ස්ථාන කිහිපයක් තිබීම ගැන යමක් කියයි යැයි ඔබ සිතන්නේ නම් සමහර විට ඔබ එය නැවත කියවිය යුතුය . එය එසේ නොවන නිසා.
jalf

10
O ජෝන්, ඔබ ප්‍රශ්නයට සැබවින්ම පිළිතුරු නොදී පිළිතුරු දීමට උත්සාහ කරන බවක් පෙනේ. එය කදිම කියවීමේ ලැයිස්තුවකි, නමුත් මෙම රචනයට සහ පොතට අසන්නාගේ සැලකිල්ල ගැන කීමට කිසිවක් නැතැයි යන ඔබේ ප්‍රකාශය සාධාරණීකරණය කිරීම සඳහා ඔබ කිසිවක් උපුටා දැක්වීමක් හෝ අක්ෂර වින්‍යාසයක් කර නැත. ඇත්ත වශයෙන්ම, අදහස් දැක්වීම් වලට පිටින් ඔබ ප්‍රශ්නය ගැන සැලකිය යුතු කිසිවක් පවසා නැත . මෙම පිළිතුර පුළුල් කිරීම සලකා බලන්න.
ෂොග්

36

ෆෝලර් සම්බන්ධ කිරීම සැමවිටම පහසුය.

SESE ට එරෙහිව යන ප්‍රධාන උදාහරණවලින් එකක් වන්නේ ආරක්ෂක වගන්ති:

ආරක්ෂක වගන්ති සමඟ කැදැලි කොන්දේසි ප්‍රතිස්ථාපනය කරන්න

සියලුම විශේෂ අවස්ථා සඳහා ආරක්ෂක වගන්ති භාවිතා කරන්න

double getPayAmount() {
    double result;
    if (_isDead) result = deadAmount();
    else {
        if (_isSeparated) result = separatedAmount();
        else {
            if (_isRetired) result = retiredAmount();
            else result = normalPayAmount();
        };
    }
return result;
};  

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

double getPayAmount() {
    if (_isDead) return deadAmount();
    if (_isSeparated) return separatedAmount();
    if (_isRetired) return retiredAmount();
    return normalPayAmount();
};  

වැඩි විස්තර සඳහා ප්‍රතිනිර්මාණය කිරීමේ 250 වන පිටුව බලන්න ...


13
තවත් නරක උදාහරණයක්: එය වෙනත්-අයිඑෆ් සමඟ පහසුවෙන් සවි කළ හැකිය.
ජැක්

1
ඔබේ උදාහරණය සාධාරණ නැත, කෙසේ නම්: ද්විත්ව getPayAmount () {double ret = normalPayAmount (); if (_isDead) ret = deadAmount (); if (_isSeparated) ret = වෙන් කළ අගය (); if (_isRetired) ret = විශ්‍රාමික මුදල (); ආපසු පැමිණීම; };
චාර්බල්

7
Har චාර්බෙල් එයම නොවේ. නම් _isSeparatedසහ _isRetiredදෙකම සත්ය විය හැකි අතර (ඒ නිසයි හැකි වන්නේ නැහැ?) ඔබ වැරදි ප්රමාණය ආපසු යන්න.
hvd

3
On කොන්චොග් "කූඩු කොන්දේසි මඟින් ආරක්ෂක වගන්තිවලට වඩා හොඳ ක්‍රියාත්මක කාලයක් ලබා දෙනු ඇත " මෙයට ප්‍රධාන වශයෙන් උපුටා දැක්වීමක් අවශ්‍ය වේ. එය කිසිසේත් විශ්වාසදායක සත්‍යයක් බවට මට සැකයක් ඇත. උදාහරණයක් ලෙස, ජනනය කළ කේතය අනුව මුල් ප්‍රතිලාභ තාර්කික කෙටි පරිපථයට වඩා වෙනස් වන්නේ කෙසේද? එය වැදගත් වුවත්, වෙනස අනන්ත සෙරෙප්පුවකට වඩා වැඩි විය හැකි අවස්ථාවක් මට සිතාගත නොහැකිය. ඒ නිසා ඔබ නොමේරූ ප්‍රශස්තිකරණය යොදන්නේ කේතය අඩු කියවිය හැකි මට්ටමකට ගෙන ඒමෙන්, තරමක් වේගවත් කේතයකට මඟ පෙන්වනු ඇතැයි ඔබ සිතන දේ පිළිබඳ ඔප්පු නොකළ න්‍යායාත්මක කරුණක් සපුරාලීම සඳහා ය. අපි එය මෙහි නොකරමු
underscore_d

1
@underscore_d, ඔබ හරි. එය සම්පාදකයා මත බොහෝ දේ රඳා පවතී, නමුත් එයට වැඩි ඉඩක් ගත හැකිය .. ව්‍යාජ එකලස් කිරීම් දෙක දෙස බලන්න, ආරක්ෂක වගන්ති ඉහළ මට්ටමේ භාෂාවලින් පැමිණෙන්නේ මන්දැයි බැලීමට පහසුය. "ඒ" පරීක්ෂණය (1); ශාඛා_ අසාර්ථක අවසානය; පරීක්ෂණය (2); ශාඛා_ අසාර්ථක අවසානය; පරීක්ෂණය (3); ශාඛා_ අසාර්ථක අවසානය; {CODE} අවසානය: ආපසු; "බී" පරීක්ෂණය (1); ශාඛා_ගුඩ් ඊළඟ 1; ආපසු; next1: පරීක්ෂණය (2); ශාඛා_ගුඩ් ඊළඟ 2; ආපසු; next2: පරීක්ෂණය (3); ශාඛා_ගුඩ් ඊළඟ 3; ආපසු; next3: {CODE} ආපසු;

11

මම මේ මාතෘකාව ගැන බ්ලොග් සටහනක් ලිව්වේ මීට ටික කලකට පෙරය.

මෙහි මූලික කාරණය නම්, මෙම රීතිය පැමිණෙන්නේ කසළ එකතු කිරීම හෝ ව්‍යතිරේක හැසිරවීම නොමැති භාෂා යුගයේ සිට ය. මෙම රීතිය නූතන භාෂාවලින් වඩා හොඳ කේතයකට මඟ පෙන්වන බව පෙන්වන විධිමත් අධ්‍යයනයක් නොමැත. මෙය කෙටි හෝ වැඩි කියවිය හැකි කේතයකට තුඩු දෙන සෑම විටම එය නොසලකා හැරීමට නිදහස් වන්න. මේ සඳහා අවධාරනය කරන ජාවා කොල්ලෝ යල් පැන ගිය, අර්ථ විරහිත රීතියක් අනුගමනය කරමින් අන්ධව හා ප්‍රශ්න නොකරති.

මෙම ප්‍රශ්නය Stackoverflow හි ද විමසා ඇත


හේයි, මට තවදුරටත් එම සබැඳියට පිවිසිය නොහැක. ඔබට තවමත් ප්‍රවේශ විය හැකි තැනක සත්කාරක අනුවාදයක් තිබේද?
අරමුදල් මොනිකාගේ නඩුව

හායි, QPT, හොඳ තැනක්. මම බ්ලොග් සටහන නැවත ගෙනැවිත් ඉහත URL යාවත්කාලීන කර ඇත. එය දැන් සම්බන්ධ විය යුතුය!
ඇන්තනි

ඊට වඩා වැඩි යමක් ඇත. SESE භාවිතා කිරීමෙන් නිවැරදිව ක්‍රියාත්මක කිරීමේ වේලාව කළමනාකරණය කිරීම වඩා පහසුය. කැදැලි කොන්දේසි බොහෝ විට කෙසේ හෝ ස්විචයකින් ප්‍රතිනිර්මාණය කළ හැකිය. එය ප්‍රතිලාභ වටිනාකමක් තිබේද නැද්ද යන්න ගැන පමණක් නොවේ.

ඒ සඳහා විධිමත් අධ්‍යයනයක් නොමැති බව ඔබ ප්‍රකාශ කිරීමට යන්නේ නම්, එයට එරෙහි වන එකකට සම්බන්ධ වීම ඔබට අවශ්‍ය වේ.
user541686

1
මෙහර්දාඩ්, ඊට සහාය දැක්වීම සඳහා විධිමත් අධ්‍යයනයක් තිබේ නම්, එය පෙන්වන්න. එච්චරයි. එරෙහිව සාක්ෂි ඉල්ලා සිටීම යනු ඔප්පු කිරීමේ භාරය මාරු කිරීමයි.
ඇන්තනි

6

බහු ප්‍රතිලාභ ප්‍රකාශයන් GOTO හි තනි ප්‍රතිලාභ ප්‍රකාශයකට සමාන කිරීමට සමාන බව සලකන්න. කඩිනම් ප්‍රකාශ සම්බන්ධයෙන්ද මෙයම වේ. මේ අනුව, මා වැනි සමහරු ඒවා සියලු අභිප්‍රායන් සහ අරමුණු සඳහා ගොටෝ ලෙස සලකති.

කෙසේ වෙතත්, මම මෙම වර්ගයේ GOTO හි හානිකර යැයි නොසිතන අතර මගේ කේතයේ සත්‍ය GOTO එකක් භාවිතා කිරීමට පසුබට නොවන්නේ නම් ඒ සඳහා හොඳ හේතුවක් මා සොයා ගන්නේ නම්.

මගේ සාමාන්‍ය රීතිය නම් GOTO ගේ ප්‍රවාහ පාලනය සඳහා පමණි. ඒවා කිසි විටෙකත් කිසිදු ලූපයක් සඳහා භාවිතා නොකළ යුතු අතර, ඔබ කිසි විටෙකත් 'ඉහළට' හෝ ​​'පසුපසට' නොයා යුතුය. (බිඳීම් / ප්‍රතිලාභ වැඩ කරන්නේ එලෙසයි)

අනෙක් අය සඳහන් කර ඇති පරිදි, පහත දැක්වෙන්නේ කියවිය යුතු හානිකර යැයි සැලකෙන GOTO ප්‍රකාශය
කෙසේ වෙතත්, මෙය 1970 දී GOTO හි අධික ලෙස භාවිතා කරන විට ලියා ඇති බව මතක තබා ගන්න. සෑම GOTO එකක්ම හානිකර නොවන අතර සාමාන්‍ය ඉදිකිරීම් වෙනුවට ඔබ ඒවා භාවිතා නොකරන තාක් කල් මම ඒවායේ භාවිතය අධෛර්යමත් නොකරමි, නමුත් සාමාන්‍ය ඉදිකිරීම් භාවිතා කිරීම ඉතා අපහසු වනු ඇත.

සමහර අවස්ථාවලදී ප්‍රයෝජනවත් නොවන සාමාන්‍ය අවස්ථාවන්හිදී කිසි විටෙකත් සිදු නොවිය යුතු අසමත් වීමක් හේතුවෙන් ඔබට යම් ප්‍රදේශයකින් පැන යාමට අවශ්‍ය අවස්ථාවන්හිදී ඒවා භාවිතා කිරීම වැරදි බව මට පෙනී ගියේය. නමුත් ඔබ මෙම කේතය වෙනම ශ්‍රිතයකට දැමීම ගැන සලකා බැලිය යුතුය, එවිට ඔබට GOTO භාවිතා කරනවා වෙනුවට ඉක්මනින් ආපසු යා හැකිය ... නමුත් සමහර විට එයද අපහසු වේ.


6
ගොටෝ වෙනුවට ආදේශ කරන සියලුම ව්‍යුහාත්මක ඉදිකිරීම් ක්‍රියාත්මක වන්නේ ගොටෝ අනුව ය. උදා: ලූප, "නම්" සහ "නඩුව". මෙය ඔවුන් නරක කරන්නේ නැත - ඇත්ත වශයෙන්ම ප්රතිවිරුද්ධයයි. එසේම, එය "අභිප්රායන් සහ අරමුණු" වේ.
ඇන්තනි

ස්පර්ශ කරන්න, නමුත් මෙය මගේ කාරණයට වෙනස් නොවේ ... එය මගේ පැහැදිලි කිරීම තරමක් වැරදියි. හා හොඳයි.
user606723

(1) ඉලක්කය එකම ක්‍රමවේදයක් හෝ ශ්‍රිතයක් තුළ පවතින තාක් කල් GOTO හොඳින් සිටිය යුතු අතර (2) කේතයෙහි දිශාව ඉදිරියට (සමහර කේත මඟ හරින්න) සහ (3) ඉලක්කය වෙනත් කැදැලි ව්‍යුහයක් තුළ නොමැත (උදා. GOTO if-case මැද සිට වෙනත් නඩුව මැද දක්වා). ඔබ මෙම නීති රීති අනුගමනය කරන්නේ නම්, GOTO හි සියලුම අනිසි භාවිතය දෘශ්‍ය හා තර්කානුකූලව ප්‍රබල කේත සුවඳක් ඇත.
මිකෝ රන්ටලයිනන්

6

එක් ප්‍රතිලාභයක් ප්‍රතිනිර්මාණය කිරීම පහසු කරයි. නැවත පැමිණීම, බිඳීම හෝ ඉදිරියට ගෙන යාම සඳහා ලූපයක් සඳහා අභ්‍යන්තර ශරීරයට “නිස්සාරණ ක්‍රමය” සිදු කිරීමට උත්සාහ කරන්න. ඔබගේ පාලන ප්‍රවාහය බිඳ දැමූ බැවින් මෙය අසාර්ථක වනු ඇත.

කාරණය වන්නේ: කිසිවෙකු පරිපූර්ණ කේතයක් ලිවීමට මවා පෑමක් නොකරන බව මම අනුමාන කරමි. එබැවින් කේතය විධිමත් ලෙස ප්‍රතිනිර්මාණය කිරීම යටතේ “වැඩිදියුණු” කර දීර්. කර ඇත. එබැවින් මගේ ඉලක්කය වනුයේ මගේ කේතය හැකිතාක් ප්‍රතිනිර්මාණය කිරීමේ මිත්‍රශීලීව තබා ගැනීමයි.

පාලක ප්‍රවාහ බ්‍රේකර් අඩංගු නම් සහ ක්‍රියාකාරීත්වය සුළු වශයෙන් පමණක් එකතු කිරීමට අවශ්‍ය නම්, කාර්යයන් සම්පූර්ණයෙන්ම ප්‍රතිසංස්කරණය කිරීමට මට ඇති ගැටලුවට බොහෝ විට මම මුහුණ දෙමි. හුදකලා කූඩුවලට නව මාවත් හඳුන්වා දීම වෙනුවට පාලන ප්‍රවාහය සම්පූර්ණයෙන්ම වෙනස් කරන බැවින් මෙය ඉතා දෝෂ සහිත වේ. ඔබට අවසානයේ ඇත්තේ එක් ප්‍රතිලාභයක් පමණක් නම් හෝ ඔබ ලූපයකින් පිටවීමට ආරක්ෂකයින් භාවිතා කරන්නේ නම් ඔබට ඇත්ත වශයෙන්ම වැඩි කැදැල්ලක් සහ කේතයක් ඇත. නමුත් ඔබ සම්පාදක සහ IDE සහාය දක්වන ප්‍රතිචක්‍රීකරණ හැකියාවන් ලබා ගනී.


විචල්‍යයන්ට ද එය අදාළ වේ. මුල් ආපසු පැමිණීම වැනි පාලන-ප්‍රවාහ-ඉදිකිරීම් භාවිතා කිරීමේ විකල්පය ඒවාය.
අඩුකිරීමේ

පවත්නා පාලන ප්‍රවාහය ආරක්ෂා වන අයුරින් ඔබේ කේතය කැබලිවලට කැඩීමට විචල්‍යයන් බොහෝ දුරට ඔබට බාධාවක් නොවේ. "උපුටා ගැනීමේ ක්‍රමය" උත්සාහ කරන්න. IDE වලට හැකි වන්නේ ඔබ ලියා ඇති දෙයින් අර්ථකථන ලබා ගැනීමට නොහැකි බැවින් පාලක ප්‍රවාහ පෙර සැකසුම් ප්‍රතික්‍රියාකාරක සිදු කිරීමට පමණි.
oopexpert

4

චක්‍රීය සංකීර්ණතාව

චක්‍රීය සංකීර්ණතාව තීරණය කිරීම සඳහා සොනාර්කූබ් බහු ප්‍රතිලාභ ප්‍රකාශයක් භාවිතා කරන බව මම දැක ඇත්තෙමි. එනිසා ප්‍රතිලාභ ප්‍රකාශ වැඩි වන තරමට චක්‍රීය සංකීර්ණතාව වැඩි වේ

ප්‍රතිලාභ වර්ගය වෙනස් කිරීම

බහුවිධ ප්‍රතිලාභ යනු අපගේ ආපසු පැමිණීමේ වර්ගය වෙනස් කිරීමට අප තීරණය කරන විට ශ්‍රිතයේ ස්ථාන කිහිපයක වෙනස් විය යුතු බවයි.

බහු පිටවීම

ආපසු හරවන ලද වටිනාකමට හේතුව කුමක්දැයි වටහා ගැනීම සඳහා කොන්දේසිගත ප්‍රකාශ සමඟ ඒකාබද්ධව තර්කනය හොඳින් අධ්‍යයනය කළ යුතු බැවින් එය නිදොස් කිරීම දුෂ්කර ය.

ප්‍රතිචක්‍රීකරණය කළ විසඳුම

බහුවිධ ප්‍රතිලාභ ප්‍රකාශ සඳහා විසඳුම වන්නේ අවශ්‍ය ක්‍රියාත්මක කිරීමේ වස්තුව නිරාකරණය කිරීමෙන් පසු ඒවා බහුඅවයවිකතාවයකින් ප්‍රතිස්ථාපනය කිරීමයි.


4
බහුවිධ ප්‍රතිලාභවල සිට ප්‍රතිලාභ අගය බහුවිධ ස්ථානවල සිටුවීම චක්‍රීය සංකීර්ණතාවය තුරන් නොකරයි, එය පිටවන ස්ථානය ඒකාබද්ධ කරයි. දී ඇති සන්දර්භය තුළ චක්‍රීය සංකීර්ණතාවයෙන් දැක්විය හැකි සියලු ගැටලු පවතී. "ආපසු හරවන ලද වටිනාකමට හේතුව කුමක්දැයි වටහා ගැනීම සඳහා කොන්දේසිගත ප්‍රකාශ සමඟ ඒකාබද්ධව තර්කනය හොඳින් අධ්‍යයනය කළ යුතු බැවින් එය නිදොස් කිරීම දුෂ්කර ය" නැවතත්, ප්‍රතිලාභ ඒකාබද්ධ කිරීමෙන් තර්කනය වෙනස් නොවේ. කේතය ක්‍රියා කරන ආකාරය අවබෝධ කර ගැනීම සඳහා ඔබ ප්‍රවේශමෙන් අධ්‍යයනය කළ යුතු නම්, එය ප්‍රතිනිර්මාණය කළ යුතුය.
විල් ඩී
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.