У який момент табуювати петлі всередині циклів?


23

Просто цікаво. Найбільше, що я коли-небудь мав, це цикл for для циклу, тому що прочитавши це від Лінуса Торвальда:

Вкладки мають 8 символів, і таким чином відступи також є 8 символами. Є єретичні рухи, які намагаються зробити відступи 4 (або навіть 2!) Символами глибокими, і це схоже на намагання визначити значення PI, яке буде 3.

Обгрунтування: Вся ідея відступу - чітко визначити, де починається і закінчується блок управління. Особливо, коли ви дивитесь на екран протягом 20 годин прямого, вам буде набагато простіше побачити, як працює відступ, якщо у вас є великі відступи.

Тепер деякі люди будуть стверджувати, що наявність 8-символьних відступів змушує код рухатись занадто далеко вправо і ускладнює читання на екрані терміналу 80 символів. Відповідь на це полягає в тому, що якщо вам потрібно більше 3-х рівнів відступу, ви все одно накрутили і повинні виправити свою програму.

https://www.kernel.org/doc/Documentation/CodingStyle

Я вважав, що для мене неприйнятною є практика переходити до третього шару циклу і реструктурувати мій код (в першу чергу Qt).

Чи жартував Лінус?

Це залежить від мови чи програми?

Чи є речі, яким абсолютно потрібні три або більше рівнів циклічного циклу?


8
Я заплутався, чому ви переходите з відступу на рівні циклу? У вас є велика цитата, що обговорює відступ, і раптом з цього випливає питання про вкладені петлі.
Пітер Б

5
Лінус, мабуть, не жартує в цьому розділі, але зауважте, що це лише один посібник зі стилів, і той самий посібник зі стилю наголошує, що "стиль кодування в ядрі дуже простий", тобто більше, ніж інші стилі.

5
@Akiva Ви не можете пройти 4-мірну матрицю, не маючи 4 вкладених циклів. Мені здається божевільним, що хтось обмежує кількість вкладених циклів, які ти можеш мати. Лінус, очевидно, був дуже загальним, і ви не повинні сприймати все, що читаєте, як святе Писання.
Alternatex

9
@Alternatex Те, що вам потрібно 4 петлі, не означає, що вони мають бути лексично вкладені. З цитати цілком очевидно, що ми говоримо про те, як організувати код, а не про виконання.

4
@delnan Я не кажу, що 4 вкладені петлі візуально приємні, і я усвідомлюю, що існують інші способи зробити це, але мені здається дурним, як ОП сприйняв слова Лінуса так буквально. 4-й рівень відступу = кінець світу. Дай мені перерву.
Alternatex

Відповіді:


19

Ядро віддає перевагу простим алгоритмам

Хоча різноманітні алгоритми можуть вимагати глибоко вкладених циклів в циклі, в контексті ядра Linux (в якому було сказано цитату), як правило, потрібні швидкі відповіді в режимі реального часу. У цьому контексті глибоке вкладення - це запах, який може вказувати на те, що потік коду є надто складним для даного домену і його, можливо, потрібно змінити через його характеристики виконання, а не з читанням чи відступом.

Крім того, ядро ​​Linux відрізняється від більшості програмного коду тим, що стосується вимог аудиторської перевірки та тестування, і, таким чином, вважатиме за краще не вбудований алгоритм 4+ рівня в одній функції. Повинно бути очевидним, щоб зрозуміти, що точно і детально робить кожен фрагмент коду , включаючи всі можливі контрольні потоки та крайові випадки. Глибоко вкладений код перешкоджає цьому.


Отже, ви вважаєте, що з мовами нижчого рівня, такими як C, глибоко вкладені петлі, як правило, більш табуйовані becauseпроекти, що використовують мови нижчого рівня, виграють від стилю кодування, який зосереджується на більш простих алгоритмах?
Аківа

4
@Akiva Я б не пов'язував це з мовами нижчого рівня або C як такими, а скоріше з доменом коду. Я думаю, що подібні вказівки застосовуватимуться до будь-якої мови при написанні коду, який повинен бути надійним, орієнтованим на безпеку та підлягати аудиту за рахунок інших речей. Наприклад, бібліотека шифрування, написана на Java або Haskell, також повинна бути написана у стилі, який забезпечує максимально прості речі, обмежує вкладення і намагається розділити все на шматки, які можна легко проаналізувати з усіма можливими наслідками.
Петерсіс

Дуже проникливий і корисний коментар / відповідь. Просто цікаво; який проект, зроблений сьогодні, який використовує мову низького рівня, не зосередився б на надійності, здатності до аудиту та безпеці?
Аківа

7
@Akiva, наприклад, код машинного навчання, де ви можете використовувати C лише з міркувань продуктивності, але не надто дбаєте про надійність та безпеку, оскільки він працюватиме всередині в контрольованих умовах. Крім того, впроваджуючи прості бізнес-функції на малих вбудованих мікроконтролерах - на практиці це часто такий бізнес, як фокус на функціях та швидкості розвитку за рахунок якості та безпеки, але використовує мови низького рівня.
Петерсіс

49

Я певною мірою перестав сприймати цю цитату серйозно на "Вкладках - 8 символів" . Вся суть табуляторів полягає в тому, що вони не є фіксованою кількістю символів (якщо щось є, вкладка - це один символ). Яке навантаження тошу. Так само я не повністю впевнений, що встановлення жорсткого і швидкого правила "трьох рівнів відступу" є розумним (стільки, як встановити жорстке правило для будь-чого, що є здоровим).

Однак обмеження рівня відступів є загалом розумною пропозицією, а не тією, що має стати для вас сюрпризом.

Зрештою, якщо вашій програмі потрібні три рівня ітерації, це саме те, що потрібно вашій програмі . Дух цитати полягає не в тому, щоб магічним чином полегшити цю вимогу від вашого проекту, а відключити логіку на функції та типи, щоб ваш код був більш чітким та виразним.

Це просто повертається до тієї ж інструкції, наведеної вище щодо рівнів відступу. Йдеться про те, як ви структуруєте свій код і зберігаєте його читабельним, бездоганним і цікавим для зміни на роки в майбутньому.


6
Я вважаю, що "декларація" про те, що вкладки мають 8 символів, саме в контексті розробки ядра. Ця цитата взята з правил кодування для конкретного проекту і не має бути загальним правилом використання, і, таким чином, очікується, що вона буде досить висловленою.
Лі Лі Райан

6
@LieRyan: Тоді це все-таки тош - кодування керівництва ні для чого не має діла, що диктує, наскільки широко я встановлюю свої вкладки! Але я підозрюю, що Лінус це знає.
Гонки легкості з Монікою

6
і, звичайно, це залежить від мови - в c # звичайно ви маєте відступ всередині простору імен, у своєму класі та у своєму методі .. ви вже на 3-х рівнях відступу, перш ніж ви навіть поговорите про те, що органи заяви оперативного управління є з відступом
PeterL

3
@LightnessRacesinOrbit Я тлумачу коментар "Вкладки - це 8 символів", це означає не те, що ви повинні особисто переглядати вкладки як 8 широкими у своєму редакторі, але для цілей інших правил у посібнику зі стилів (наприклад, "Обмеження на довжину рядків" є 80 стовпців, і це вкрай бажаний ліміт. ") вкладки повинні розглядатися як 8 стовпців, це також стосується інших правил щодо вирівнювання аргументів у викликах функцій. Знову ж таки, я не думаю, що намір цього рядка змушує вас переглядати вкладки таким чином, я вже робив виправлення ядра за допомогою 4 широких вкладок і поповнював код в кінці.
Vality

4
@underscore_d: Схоже, я помиляюся: Outside of comments, documentation and except in Kconfig, spaces are never used for indentation, and the above example is deliberately broken.- 6 абзаців від цитати в ОП.
slebetman

16

Суть така ж, як і для будь-яких конструкцій управління потоком: якщо код важко зрозуміти, вам потрібно його перефактурувати. Якщо ви робите кілька простих маніпуляцій з багатовимірним масивом, то, якщо петлі вкладені в п’ять-шість глибоких, може бути доречним, доки логіка в самій внутрішній петлі є простою. Однак якщо ви обробляєте складну ділову логіку, а тіло вашого циклу - це десяток ліній або більше, ви, ймовірно, не захочете вкладати цю глибоку петлю. Ви можете спробувати обчислити циклічну складність коду, але те, що воно насправді зводиться, - це читабельність та ремонтопридатність коду, про який йде мова.


11
Саме так. Дуже легко вважати, що Торвальдс - лун. (Він, звичайно,.) Він може бути занадто жорстким на ваш смак, але він описує справжню проблему розвитку, яка викликає реальні проблеми. Не потрібно робити саме те, що він каже, але варто подумати, чому він це говорить.
Мізерний Роджер

7
@ScantRoger Власне, цитата Торвальда звучить занадто жорстко, якщо ви не отримаєте його почуття гумору. Як я пам’ятаю, раніше в тому ж документі він пропонує роздрукувати копію керівних принципів стилю кодування GNU, лише щоб записати їх під час якоїсь церемонії. Ви навряд чи це сприймете серйозно, чи не так? У цій цитаті його головним моментом є визначення відступу для ядра Linux на вісім пробілів, нічого більше, і нічого менше, саме це він жорсткий. Останнє речення полягає лише в тому, щоб підкреслити цю точку, а не сказати, що ви не повинні використовувати більше рівнів відступу - жодної жорсткості не мається на увазі.
cmaster

1
@cmaster Дякую за контекст, прямо зараз! Відповідаючи на ваш запит, я навряд чи сприймаю щось серйозно. ;)
Мізерний Роджер

2
@cmaster, а потім читає його відповіді на запити про тягнення github та довжину рядка повідомлень про фіксацію. Він є загальним випадком горіха.
Гусдор

3
Церемоніально записувати вказівки щодо кодування GNU насправді не потрібно, але це повністю в порядку в будь-який момент часу.
dmckee

13

Чи жартував Лінус?

Композиція написана в грайливому стилі, що говорить про те, що автор знайомий із тим, як обговорюється стиль кодування серед серйозних практикуючих: У всіх нас є свої уподобання, і ми захищаємо їх шалено, але язиком хоча б частково в щоці. Ми прекрасно розуміємо, що значна частина цього питання є лише питанням особистого смаку. Він говорить так багато слів, "Coding style is very personal, and I won't _force_ my views on anybody"- принаймні поза кодом, який він особисто дотримується. Але узгодженість стилю в даному проекті - дуже гарна ідея. Я набагато скоріше кодую стиль, який мені не подобається, ніж мати справу з декількома стилями в даній функції.

Ось приклад чітко грайливого написання:

However, there is one special case, namely functions: they have the
opening brace at the beginning of the next line, thus:

int function(int x)
{
    body of function
}

Heretic people all over the world have claimed that this inconsistency
is ...  well ...  inconsistent, but all right-thinking people know that
(a) K&R are _right_ and (b) K&R are right.  Besides, functions are
special anyway (you can't nest them in C).

Грайливий (1).

Це, мабуть, хороша порада намагатися не допускати відступу, щоб не виходити з-під контролю, хоча максимум трьох рівнів може бути гіперболічним. Я не збираюся схрещувати джерело ядра та рахувати послідовності чотирьох символів вкладки, але я б покладав гроші, що ви зможете знайти хоча б одну, яку написав Торвальдс.

З іншого боку, якщо хтось може написати ядро ​​Linux, не часто перевищуючи три рівні відступів, трирівневий ліміт може бути вправою, яку варто спробувати на деякий час у власному коді, просто щоб побачити, куди він веде вас. Ви не знаєте, що зміна статі. Це не довічне зобов'язання.

Якщо ви натрапите на когось в Інтернеті, який вважає, що він розуміє програмування набагато краще, ніж Торвальдс (2), ну, ви знаєте, про які люди люблять велику розмову в Інтернеті.

З іншого боку, він кримінально помиляється щодо восьмикосмічних вкладок. Це захоплення людини, яку слід тримати стримано і годувати через проріз. Чотири пробіли, очевидно, правильно.

(1) Але зауважте, як він помилково ставить простір перед еліпсами, і два пробіли після них, і два пробіли після повної зупинки. WRONG, WRONG, WRONG. І тоді він має нахабний жовт, щоб забити єретиків. Єретик - це ти, Торвальдс! ЦЕ ТИ!

(2) Якщо ви хочете поговорити про " розуміння того, як створити систему управління джерелами ", можливо, буде дещо дискусій.

Примітка. Шановний користувач, який неодноразово надсилав одне й те саме редагування: Форматування в цитованому матеріалі зберігається саме так, як його передбачав автор. Це тому, що це з нарису про форматування тексту фіксованої ширини, написаного текстом фіксованої ширини, тим, хто присвятив форматуванню тексту фіксованої ширини неабияку думку. Форматування є усвідомленою та обдуманою частиною задуму автора, і стосується теми.

Крім того, я звернувся до цього форматування у власному тексті. Якщо ви витягнете попереднє форматування, моя виноска (1) стає химерною. Якщо попереднє форматування буде видалено, таким повинен бути текст моєї виноски (1), що стосується пар пробілів після повних зупинок у кінці речень. Я бачу обґрунтування для видалення цієї виноски в будь-якому випадку, тому що вона менш смішна, ніж здавалося, коли я писав її. Але видаляти форматування, не видаляючи виноску, - це не корисно.


3
Чудова відповідь. Один із випадків, який заслуговує на +2 ... (Примітка. У .цьому коментарі немає помилок пробілу ;-))
cmaster

2
Вступний абзац Лінуса, який ви вказали, дуже важливий, тому дякую вам за це! Я думаю, що перше речення також є дуже важливим для контексту, зокрема preferred coding style, якbut this is what goes for anything that I have to be able to maintain
Кріс Хаас

9

У Лінуса дуже тупий стиль виступу та сухе почуття гумору, але він не жартував у цьому випадку. Бувають ситуації, коли алгоритму потрібно вкладати глибше двох рівнів, але ви можете це досягти, використовуючи інші засоби, ніж відступ коду. Посібник зі стилю ядра Linux настійно віддає перевагу цим іншим методам через складність у підтримці глибоко вкладених циклів, і саме тут говорить Лінус.

У деяких прикладах альтернативних методів можна використовувати рекурсію, розділити внутрішні петлі на власні функції або зробити проміжні структури даних.

Надмірне гніздування - один із тих випадків, які простіше писати, але важче читати. Встановлення великої глибини вкладки - це спосіб Лінуса зробити так, що це також дратує і писати.


3

Є багато питань, де поради відрізняються від того, хто ставить питання, ніж для того, хто не запитує. Якщо ви запитаєте "Чи повинен я коли-небудь мати петлі, які вкладені більш ніж на два рівні глибиною", то для вас, людина, яка задає це питання, відповідь "НІ". Якщо ви запитаєте, тоді не робіть цього. Якщо у вас є достатній досвід, який вам не потрібно запитувати, то ви знаєте, яка правильна відповідь у кожному конкретному випадку. І не сперечайтесь, якщо ви не згодні з відповіддю, оскільки відповідь не для вас.


1

Це, мабуть, є підручником із хвоста, що витає собаку.

Якщо у вас 80-символьний дисплей, то, звичайно, ви намагаєтеся зробити код найкращим чином, навіть якщо він не створює найкращої структури для коду .

Вирішення решти балів продовжуйте:

Я подумав, що це неприйнятна практика.

Я думаю, ти занадто багато читаєш у цьому. Протистояти прагненню сприймати все, що ви читаєте, як Євангеліє, не розуміючи належним чином контексту.

Він жартував?

Важко визначити контекст, але бачу мою початкову точку вище.

Це залежить від мови чи програми?

Дуже так. Візьміть будь-яку мову основного / середнього діапазону, де ви, швидше за все, кодуєте термінал (або емулятор терміналу).

Чи є речі, яким абсолютно потрібні три або більше рівнів циклічного циклу?

Так, це дуже часто зустрічається в деяких алгоритмах грубої сили. Дивіться проблему 31 про проект Euler. Це класичний приклад проблеми, яку можна вирішити грубою силою, використовуючи ряд петель (8, якщо бути точним).


1
Схоже, що проблема 31 не вимагає грубої сили і може бути вирішена за допомогою алгоритму динамічного програмування (редагувати: це означає, що ваша структура коду не найкраща, якщо ви використовуєте алгоритм грубої сили). Крім того, суть Лінуса полягає в тому, що якщо ваш код вимагає багатьох рівнів відступу, це, ймовірно, не найкраща структура для коду.
Вінсент Савард

2
@VincentSavard Ніколи не говорив, що це вимагає грубої сили. Не погоджуйтесь із вашим другим пунктом - іноді це найяскравіший і найкоротший підхід, не кажучи вже про найефективніший в деяких випадках.
Роббі Ді

1
З такою проблемою я зазвичай не відступаю петлі. Я думаю, у мене був один випадок з 20 вкладеними петлями, абсолютно тривіальним для запису, і жодним відступом, щоб ви могли бачити, що петлі були майже однаковими.
gnasher729

1
@RobbieDee: Думаю, що ваш приклад проблеми, яку вирішує багато циклів, полягає в тому, що ваш алгоритм не настільки ефективний, як динамічне рішення програмування, для якого не потрібно стільки рівнів відступу. Таким чином, як сказав Лінус, ваші рівні відступи можна усунути за допомогою кращого рішення. Ви також неправильно зрозуміли мій другий пункт, тому що я згоден з тим, що ви сказали. Іноді це найкраще рішення. Іноді це не часто, і це мало ймовірно.
Вінсент Савард

1
Цитата Лінуса явно прямо говорить про те, що якщо якийсь код вимагає чогось на зразок грубої сили цієї Проблеми-31, то все одно ви накрутили - це не буде ні швидким, ні простим, і операції з ядром повинні бути швидкими і простими. Включення будь-якого алгоритму O (n ^ 4) в ядро ​​є значним ризиком виконання або відмови в обслуговуванні, тому в цьому контексті рекомендація просто попереджає, що це ознака коду, який може бути принципово невідповідним і потрібним в Linux.
Петерсіс

0

Чи жартував Лінус?

Ні, це офіційні вказівки.

Це залежить від мови чи програми?

Вказівки щодо кодування зазвичай залежать від мови та програми, однак глибоко вкладений код завжди оподатковує читача.

Проблема з вкладеним кодом полягає в тому, що в цілому він збільшує цикломатичну складність: тобто чим більше вкладений код, тим більше потенційних шляхів виконання існує у функції. Комбінаторний вибух потенційних шляхів виконання ускладнює міркування про код, і тому його слід уникати взагалі.

То чому 3? Суб'єктивне керівництво щодо кодування важко застосувати і неможливо автоматично застосувати. Встановлення об'єктивної настанови щодо кодування на максимальному рівні відступу потребує узгодження числа: у ядрі Linux вони вибрали 3.

Це довільно і, мабуть, їм достатньо.

Чи є речі, яким абсолютно потрібні три або більше рівнів циклічного циклу?

Мабуть, алгоритм, однак, в достатньо виразних мовах ви завжди можете перефактурувати код на менші шматки (будь то з функціями чи із закриттям).

Ви, очевидно, можете написати примхливий код з невеликим вкладенням і безліччю дрібних функцій, що дзвонять один одному, не пишучи жодного разу їх контракт ...

... однак, малі функції з чіткими договорами набагато простіше перевірити, ніж великі функції з чіткими контрактами в цілому.


2
Хоча це може бути офіційним керівництвом, тривіально знайти місця в коді ядра, де керівництво не виконується.
MikeB

1
@MikeB: Тим більше причин автоматично застосовувати вказівки ...
Matthieu M.

1
@MatthieuM. Ви впевнені, що розумієте різницю між настановами та обов'язковими вимогами? Як загальне "правило" (керівництво, якщо вам подобається), вказівки більше схожі на рекомендації і не застосовуються.
Брендан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.