stringtranslate.com

Условный (компьютерное программирование)

Диаграмма потока «если-то-иначе»
Вложенная диаграмма потока if–then–else

В информатике условные операторы ( то есть условные операторы , условные выражения и условные конструкции ) — это конструкции языка программирования , которые выполняют различные вычисления или действия или возвращают различные значения в зависимости от значения логического выражения, называемого условием .

Условные операторы обычно реализуются путем выборочного выполнения инструкций. Хотя динамическая диспетчеризация обычно не классифицируется как условная конструкция, это еще один способ выбора между альтернативами во время выполнения .

Терминология

Условные операторы — это императивные конструкции, выполняемые для побочного эффекта, в то время как условные выражения возвращают значения. Многие языки программирования (например, C) имеют отдельные условные операторы и условные выражения. Хотя в чистом функциональном программировании условные выражения не имеют побочных эффектов , многие языки с условными выражениями (например, Lisp) поддерживают условные побочные эффекты.

Если–то(–иначе)

Конструкция if–thenor if–then–elseиспользуется во многих языках программирования. Хотя синтаксис различается от языка к языку, базовая структура (в форме псевдокода ) выглядит следующим образом:

Если (булево условие) Тогда (последующий)Еще (альтернатива)Конец Если

Например:

Если запас=0 Тогда сообщение= заказать новый товарЕще сообщение= есть на складеКонец Если

В приведенном выше примере кода часть, представленная (логическим условием), представляет собой условное выражение , имеющее внутреннее значение (например, оно может быть заменено одним из значений Trueили False), но не имеющее внутреннего значения. Напротив, комбинация этого выражения, и If, Thenокружающего его, и консеквента, который следует за ним, представляет собой условное утверждение , имеющее внутреннее значение (например, выражающее связное логическое правило), но не имеющее внутреннего значения.

Когда интерпретатор находит If, он ожидает логическое условие – например, x > 0, что означает «переменная x содержит число больше нуля» – и оценивает это условие. Если условие равно , выполняются trueоператоры, следующие за . В противном случае выполнение продолжается в следующей ветви – либо в блоке (что обычно необязательно), либо, если ветви нет, то после .thenelse elseend If

После выполнения любой из ветвей управление возвращается к точке после end If.

История и развитие

В ранних языках программирования, особенно в некоторых диалектах BASIC в домашних компьютерах 1980-х годов , if–thenоператор мог содержать только GOTOоператоры (эквивалентные инструкции ветвления ). Это привело к трудночитаемому стилю программирования, известному как спагетти-программирование , с программами в этом стиле, называемыми спагетти-кодом . В результате структурное программирование , которое позволяет (фактически) произвольным операторам помещаться в блоки операторов внутри оператора if, приобрело популярность, пока не стало нормой даже в большинстве кругов программирования BASIC. Такие механизмы и принципы были основаны на более старом, но более продвинутом семействе языков ALGOL , и языки, подобные ALGOL, такие как Pascal и Modula-2, влияли на современные варианты BASIC в течение многих лет. Хотя возможно, используя только GOTOоператоры в if–thenоператорах, писать программы, которые не являются спагетти-кодом и так же хорошо структурированы и читабельны, как программы, написанные на структурном языке программирования, структурное программирование упрощает это и обеспечивает это. Структурированные if–then–elseоператоры, подобные приведенному выше примеру, являются одним из ключевых элементов структурного программирования и присутствуют в большинстве популярных языков программирования высокого уровня, таких как C , Java , JavaScript и Visual Basic .

Проблема «зависания else»

Ключевое elseслово сделано для того, чтобы нацеливаться на определенный if–thenоператор, предшествующий ему, но для вложенных if–then операторов классические языки программирования, такие как ALGOL 60, с трудом определяли, какой конкретный оператор следует нацеливать. Без четких границ для какого оператора какой, elseключевое слово может нацеливаться на любой предшествующий if–thenоператор во вложенном состоянии, как проанализировано.

если а, то  если б, то с, иначе с2

можно проанализировать как

если а, то ( если б, то с) иначе с2

или

если а то ( если б то с иначе с2)

в зависимости от того, elseсвязан ли с первым ifили вторым if. Это известно как проблема висячего else и решается разными способами в зависимости от языка (обычно с помощью end ifоператора или {...}скобок).

Иначе если

Используя else if, можно объединить несколько условий. Будут выполнены только операторы, следующие за первым условием, которое будет признано истинным. Все остальные операторы будут пропущены.

если условие то  -- операторы elseif условие то  -- еще операторы elseif условие то  -- еще операторы;...else  -- другие операторы; конец if ;

Например, для магазина, предлагающего скидку на товар до 30%:

если скидка < 11% то распечатать (вам придется заплатить 30 долларов)elseif скидка<21% тогда распечатать (вам придется заплатить 20 долларов)elseif скидка<31% тогда распечатать (вам придется заплатить 10 долларов)конец, если ;

В приведенном выше примере, если скидка составляет 10%, то первый оператор if будет оценен как истинный и будет выведено сообщение «you have to pay $30». Все остальные операторы ниже первого оператора if будут пропущены.

Например elseif, в языке Ada оператор является просто синтаксическим сахаром для elsefollowing by if. В Ada разница в том, что end ifтребуется только один, если использовать elseifвместо elsefollowing by if. PHP использует elseifключевое слово [1] как для своих фигурных скобок, так и для синтаксисов двоеточия. Perl предоставляет ключевое слово elsif, чтобы избежать большого количества фигурных скобок, которые потребовались бы для множественных операторов ifand else. Python использует специальное ключевое слово , elifпоскольку структура обозначается отступом, а не фигурными скобками, поэтому повторное использование elseand ifпотребовало бы увеличения отступа после каждого условия. Некоторые реализации BASIC , такие как Visual Basic , [2] тоже используют ElseIf. Аналогично, более ранние оболочки UNIX (позже объединенные в синтаксис оболочки POSIX [3] ) тоже используют elif , но предоставляют возможность разделения пробелами, переносами строк или и тем, и другим.

Однако во многих языках, более непосредственно произошедших от Algol, таких как Simula , Pascal , BCPL и C , этот специальный синтаксис для else ifконструкции отсутствует, как и во многих синтаксических производных C , таких как Java , ECMAScript и т. д. Это работает, поскольку в этих языках любой отдельный оператор (в данном случае ...) может следовать за условным оператором, не будучи заключенным в блок.if cond

Этот выбор дизайна имеет небольшую «стоимость». Каждая else ifветвь фактически добавляет дополнительный уровень вложенности. Это усложняет работу компилятора (или людей, которые пишут компилятор), поскольку компилятор должен анализировать и реализовывать произвольно длинные else ifцепочки рекурсивно.

Если все термины в последовательности условных операторов проверяют значение одного выражения (например, if x=0... else if x=1... else if x=2...), альтернативой является оператор switch , также называемый оператором case или оператором select. Наоборот, в языках, в которых нет оператора switch, они могут быть получены с помощью последовательности else ifоператоров.

Выражения «если–то–иначе»

Многие языки поддерживают выражения if , которые похожи на операторы if, но возвращают значение в качестве результата. Таким образом, они являются истинными выражениями (которые оцениваются как значение), а не операторами (которые могут быть недопустимы в контексте значения).

Семья Алгол

АЛГОЛ 60 и некоторые другие члены семейства АЛГОЛ допускают if–then–elseв качестве выражения:

 myvariable := если x > 20, то 1, иначе 2

Диалекты Лиспа

В диалектах Lisp Scheme , Racket и Common Lisp  – первый из которых был в значительной степени вдохновлен ALGOL:

;; Схема ( define myvariable ( if ( > x 12 ) 1 2 )) ; Присваивает 'myvariable' значение 1 или 2, в зависимости от значения 'x'        
;; Common Lisp ( let (( x 10 )) ( setq myvariable ( if ( > x 12 ) 2 4 ))) ; Присваивает 'myvariable' значению 2           

Хаскелл

В Haskell 98 есть только выражение if , нет оператора if , и эта elseчасть обязательна, так как каждое выражение должно иметь некоторое значение. [4] Логика, которая в других языках выражалась бы с помощью условных операторов, обычно выражается с помощью сопоставления с образцом в рекурсивных функциях.

Поскольку Haskell ленив , можно записывать управляющие структуры, такие как if , как обычные выражения; ленивая оценка означает, что функция if может оценивать только условие и соответствующую ветвь (где строгий язык оценивал бы все три). Это можно записать так: [5]

если ' :: Bool -> a -> a -> a если ' True x _ = x если ' False _ y = y                  

C-подобные языки

В языках C и C-подобных есть специальный тернарный оператор ( ?: ) для условных выражений с функцией, которая может быть описана следующим шаблоном:

condition ? evaluated-when-true : evaluated-when-false

Это означает, что его можно встраивать в выражения, в отличие от операторов if, в языках типа C:

my_variable = x > 10 ? "foo" : "bar" ; // В языках типа C         

что можно сравнить с выражениями if–then–else в языке Algol (в отличие от оператора ) (и аналогичными в Ruby и Scala, среди прочих).

Чтобы сделать то же самое с помощью оператора if, потребовалось бы более одной строки кода (согласно типичным соглашениям о компоновке) и потребовалось бы упомянуть «my_variable» дважды:

если ( x > 10 ) my_variable = "foo" ; иначе my_variable = "bar" ;         

Некоторые утверждают, что явный оператор if/then легче читать и что он может компилироваться в более эффективный код, чем тернарный оператор, [6] в то время как другие утверждают, что краткие выражения легче читать, чем операторы, разбитые на несколько строк и содержащие повторения.

Маленький базовый

x = TextWindow.ReadNumber () If ( x > 10 ) Then TextWindow.WriteLine ( " Моя переменная называется 'foo'." ) Else TextWindow.WriteLine ( " Моя переменная называется 'bar'. " ) EndIf        

Во-первых, когда пользователь запускает программу, появляется курсор, ожидающий, пока читатель введет число. Если это число больше 10, на экране отображается текст «Моя переменная называется 'foo'». Если число меньше 10, на экране печатается сообщение «Моя переменная называется 'bar'».

Визуальный базовый

В Visual Basic и некоторых других языках предусмотрена функция IIf, которая может использоваться как условное выражение. Однако она не ведет себя как истинное условное выражение, поскольку всегда оцениваются обе ветви: истинная и ложная; просто результат одной из них отбрасывается, а результат другой возвращается функцией IIf.

Тсл

В Tcl if это не ключевое слово, а функция (в Tcl известная как команда или proc). Например

если { $x > 10 } { выводит "Фу!" }      

вызывает функцию с именем, ifпередавая 2 аргумента: первый — условие, а второй — истинная ветвь. Оба аргумента передаются как строки (в Tcl все, что находится в фигурных скобках, является строкой).

В приведенном выше примере условие не оценивается перед вызовом функции. Вместо этого реализация функции ifполучает условие как строковое значение и отвечает за оценку этой строки как выражения в области действия вызывающего. [7]

Такое поведение возможно при использовании команд uplevelи expr:

Uplevel позволяет реализовать новые конструкции управления как процедуры Tcl (например, uplevel можно использовать для реализации конструкции while как процедуры Tcl). [8]

Поскольку ifэто на самом деле функция, она также возвращает значение:

Возвращаемое значение команды — это результат выполненного скрипта тела или пустая строка, если ни одно из выражений не было ненулевым и не было bodyN. [9]

Ржавчина

В Rustif всегда является выражением. Он вычисляется в значение любой выполненной ветви или в тип модуля , ()если ветвь не выполнена. Если ветвь не предоставляет возвращаемого значения, она вычисляется в ()по умолчанию. Чтобы гарантировать, что ifтип выражения известен во время компиляции, каждая ветвь должна вычисляться в значение того же типа. По этой причине ветвь elseфактически обязательна, если только другие ветви не вычисляются в (), потому что ifбез elseвсегда может вычисляться в ()по умолчанию. [10]

// Присвоить my_variable некоторое значение в зависимости от значения x let my_variable = if x > 20 { 1 } else { 2 };           // Этот вариант не скомпилируется, так как 1 и () имеют разные типы let my_variable = if x > 20 { 1 };        // Значения можно опустить, если они не нужны , если x > 20 { println! ( "x больше 20" ); }     

Защищенные условные предложения

Язык защищенных команд (GCL) Эдсгера Дейкстры поддерживает условное выполнение как список команд, состоящий из булевского охранника (соответствующего условию ) и соответствующего ему оператора. В GCL оценивается ровно один из операторов, охранники которого истинны, но какой именно — произвольно. В этом коде

если G0 → S0 □ Г1 → С1... □ Гн → Снфи

G i - это охранники, а S i - это утверждения. Если ни один из охранников не истинен, поведение программы не определено.

GCL в первую очередь предназначен для рассуждений о программах, но похожие нотации реализованы в Concurrent Pascal и Occam .

Арифметика если

До версии Fortran 77 в языке Fortran существовал арифметический оператор if , который переходил к одной из трех меток в зависимости от того, равен ли его аргумент e e < 0, e = 0, e > 0. Это был самый ранний условный оператор в Fortran. [11]

Синтаксис

ЕСЛИ ( е ) метка1 , метка2 , метка3    

Где e — любое числовое выражение (не обязательно целое число).

Семантика

Это эквивалентно этой последовательности, где e вычисляется только один раз.

ЕСЛИ ( e.LT.0 ) GOTO метка1 ЕСЛИ ( e.EQ.0 ) GOTO метка2 ЕСЛИ ( e.GT.0 ) GOTO метка3               

Стилистика

Арифметический оператор if является неструктурированным управляющим оператором и не используется в структурном программировании .

На практике было замечено, что большинство арифметических IFвыражений ссылаются на следующее выражение с одной или двумя метками.

Это был единственный оператор условного управления в оригинальной реализации Fortran на компьютере IBM 704. На этом компьютере код операции test-and-branch имел три адреса для этих трех состояний. Другие компьютеры имели бы регистры «флагов», такие как положительный, нулевой, отрицательный, четный, переполнение, перенос, связанные с последними арифметическими операциями, и использовали бы инструкции, такие как «Переход, если аккумулятор отрицательный», затем «Переход, если аккумулятор нулевой» или аналогичные. Обратите внимание, что выражение вычисляется только один раз , и в таких случаях, как целочисленная арифметика, где может произойти переполнение, флаги переполнения или переноса также учитывались бы.

Объектно-ориентированная реализация в Smalltalk

В отличие от других языков, в Smalltalk условный оператор не является языковой конструкцией , а определяется в классе Booleanкак абстрактный метод, который принимает два параметра, оба замыкания . Booleanимеет два подкласса, Trueи False, которые оба определяют метод, Trueвыполняя только первое замыкание, Falseвыполняя только второе замыкание. [12]

var  =  условие  ifTrue: [ 'foo' ] ifFalse: [ 'bar' ]

JavaScript

JavaScript использует операторы if-else, аналогичные операторам в языках C. Булево значение принимается в скобках между зарезервированным ключевым словом if и левой фигурной скобкой.

if ( Math . random () < 0.5 ) { console . log ( "Выпал орел!" ); } else { console . log ( "Выпал решка!" ); }        

В приведенном выше примере принимается условие, Math.random() < 0.5которое выводит, trueесли случайное значение с плавающей точкой между 0 и 1 больше 0,5. Оператор использует его для случайного выбора между выводом You got Heads!или You got Tails!на консоль. Операторы Else и else-if также могут быть соединены после фигурной скобки оператора, предшествующего ему, столько раз, сколько необходимо, как показано ниже:

var x = Math.random (); if ( x < 1 / 3 ) { console.log ( " Победил один человек!" ) ; } else if ( x < 2 / 3 ) { console.log ( " Победили два человека!" ); } else { console.log ( " Ничья среди трех участников!" ); }                  

Лямбда-исчисление

В лямбда-исчислении концепция условного оператора if-then-else может быть выражена с помощью следующих выражений:

правда = λx. λy. xложь = λx. λy. yеслиТогдаЕще = (λc. λx. λy. (cxy))
  1. true принимает до двух аргументов, и как только оба аргумента указаны (см. каррирование ), возвращается первый указанный аргумент.
  2. false принимает до двух аргументов и после предоставления обоих (см. карринг ) возвращает второй заданный аргумент.
  3. ifThenElse принимает до трех аргументов, и как только все они предоставлены, он передает как второй, так и третий аргумент первому аргументу (который является функцией, которая принимает два аргумента и выдает результат). Мы ожидаем, что ifThenElse будет принимать только true или false в качестве аргумента, оба из которых проецируют заданные два аргумента на свой предпочтительный единственный аргумент, который затем возвращается.

Примечание : если ifThenElse переданы две функции как левое и правое условные операторы, необходимо также передать пустой кортеж () в результат ifThenElse, чтобы фактически вызвать выбранную функцию, в противном случае ifThenElse просто вернет объект функции без вызова.

В системе, где числа могут использоваться без определения (например, Lisp, традиционная бумажная математика и т. д.), вышеизложенное можно выразить в виде одного замыкания ниже:

 (( λистина. λложь. λеслиТогда. ( еслиТогда истина 2 3 ) )( λx. λy. x )( λx. λy. y )( λc. λl. λr. c l r ))                

Здесь true, false и ifThenElse привязаны к своим соответствующим определениям, которые передаются в их область действия в конце их блока.

Действующая аналогия JavaScript (использующая только функции одной переменной для строгости) выглядит следующим образом:

 var computingResult = (( _true => _false => _ifThenElse => _ifThenElse ( _true )( 2 )( 3 ) )( x => y => x )( x => y => y )( c => x => y => c ( x )( y )));                          

Приведенный выше код с многопеременными функциями выглядит следующим образом:

 var computingResult = (( _true , _false , _ifThenElse ) => _ifThenElse ( _true , 2 , 3 ) )(( x , y ) => x , ( x , y ) => y , ( c , x , y ) => c ( x , y ));                       

Ниже приведена еще одна версия предыдущего примера без системы, где предполагаются числа.

В первом примере показана первая ветвь, а во втором — вторая ветвь.

 (( λистина. λложь. λеслиТогдаЕльсе. ( еслиТогдаЕльсе истина ( λПерваяВетка. ПерваяВетка ) ( λВтораяВетка. ВтораяВетка )) )( λx. λy. x )( λx. λy. y )( λc. λl. λr. c l r ))                   (( λистина. λложь. λеслиТогдаЕльсе. ( еслиТогдаЕльсе ложь ( λПерваяВетка. ПерваяВетка ) ( λВтораяВетка. ВтораяВетка )) )( λx. λy. x )( λx. λy. y )( λc. λl. λr. c l r ))                  

Smalltalk использует похожую идею для своих истинных и ложных представлений, при этом True и False являются одиночными объектами, которые по-разному реагируют на сообщения ifTrue/ifFalse.

Раньше Haskell использовал именно эту модель для своего типа Boolean, но на момент написания большинство программ на Haskell использовали синтаксический сахар — конструкцию «if a then b else c», которая, в отличие от ifThenElse, не компонуется, если только не обернута в другую функцию или не реализована повторно, как показано в разделе Haskell этой страницы.

Операторы case и switch

Операторы switch (в некоторых языках операторы case или многоканальные ветвления) сравнивают заданное значение с указанными константами и выполняют действие в соответствии с первой совпавшей константой. Обычно есть положение для действия по умолчанию ('else','internal'), которое будет выполнено, если совпадение не будет успешным. Операторы switch могут допускать оптимизации компилятора , такие как таблицы поиска . В динамических языках случаи могут не ограничиваться константными выражениями и могут распространяться на сопоставление с образцом , как в примере скрипта оболочки справа, где '*)' реализует случай по умолчанию как регулярное выражение, совпадающее с любой строкой.

Сопоставление с образцом

Сопоставление с образцом можно рассматривать как альтернативу операторам if–then–else и case . Оно доступно во многих языках программирования с функциями функционального программирования, таких как Wolfram Language , ML и многих других. Вот простой пример, написанный на языке OCaml :

сопоставить  фрукты  с |  "apple"  ->  приготовить  пирог |  "coconut"  ->  приготовить  dango_mochi |  "banana"  ->  смешать ;;

Сила сопоставления с образцом заключается в возможности сжато сопоставлять не только действия, но и значения с образцами данных. Вот пример, написанный на Haskell , который иллюстрирует обе эти возможности:

карта _ [] = [] карта f ( h : t ) = f h : карта f t               

Этот код определяет функцию map , которая применяет первый аргумент (функцию) к каждому из элементов второго аргумента (списка) и возвращает результирующий список. Две строки — это два определения функции для двух видов аргументов, возможных в этом случае — один, когда список пуст (просто возвращается пустой список), и другой случай, когда список не пуст.

Сопоставление с образцом, строго говоря, не всегда является конструкцией выбора, поскольку в Haskell можно написать только одну альтернативу, которая гарантированно всегда будет сопоставлена ​​– в этой ситуации она не используется как конструкция выбора, а просто как способ привязать имена к значениям. Однако она часто используется как конструкция выбора в языках, в которых она доступна.

Условные операторы на основе хэша

В языках программирования, имеющих ассоциативные массивы или сопоставимые структуры данных, таких как Python , Perl , PHP или Objective-C , их использование для реализации условного присваивания является идиоматичным. [13]

pet  =  input ( "Введите тип питомца, которого вы хотите назвать: " ) known_pets  =  {  "Собака" :  "Фидо" ,  "Кошка" :  "Мяусс" ,  "Птица" :  "Твити" , } my_name  =  known_pets [ pet ]

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

Предикация

Альтернативой инструкциям условного перехода является предикация . Предикация — это архитектурная особенность, которая позволяет выполнять инструкции условно, а не изменять поток управления .

Перекрестная ссылка системы выбора

Эта таблица относится к последней спецификации языка для каждого языка. Для языков, не имеющих спецификации, ссылаются на последнюю официально выпущенную реализацию.

  1. ^ Это относится к сопоставлению с образцом как к отдельной условной конструкции в языке программирования — в отличие от простой поддержки сопоставления с образцом строки, такой как поддержка регулярных выражений .
  2. 1 2 Директива #ELIF используется в подъязыке препроцессора , который используется для изменения кода перед компиляцией и для включения других файлов.
  3. 1 2 3 4 5 6 Часто встречающееся в языках семейства C, а также в COBOL и Haskell, это не языковая особенность, а набор вложенных и независимых операторов if then else, объединенных с определенной компоновкой исходного кода. Однако это также означает, что отдельная конструкция else–if на самом деле не нужна в этих языках. else if
  4. 1 2 В Haskell и F# отдельная конструкция выбора констант не нужна, поскольку ту же задачу можно выполнить с помощью сопоставления с образцом.
  5. ^ В caseконструкции Ruby сопоставление регулярных выражений является одной из доступных альтернатив условного управления потоком. Для примера см. этот вопрос Stack Overflow.
  6. 1 2 SQL имеет две похожие конструкции, которые выполняют обе роли, обе введены в SQL-92 . Выражение "searched" работает как , тогда как выражение "simple ": работает как оператор switch. Подробности и примеры см. в Case (SQL) .CASECASE WHEN cond1 THEN expr1 WHEN cond2 THEN expr2 [...] ELSE exprDflt ENDif ... else if ... elseCASECASE expr WHEN val1 THEN expr1 [...] ELSE exprDflt END
  7. ^ Арифметика ifустарела в Fortran 90.
  8. ^ Сопоставление с образцом было добавлено в Ruby 3.0. [16] Некоторые конструкции сопоставления с образцом все еще являются экспериментальными.

Смотрите также

Ссылки

  1. ^ PHP-синтаксис elseif
  2. ^ Синтаксис Visual Basic ElseIf
  3. ^ Синтаксис стандартной оболочки POSIX
  4. ^ Язык и библиотеки Haskell 98: Пересмотренный отчет
  5. ^ "Предложение If-then-else на HaskellWiki"
  6. ^ "Советы по эффективному использованию языка C № 6 – Не используйте тернарный оператор « Stack Overflow». Embeddedgurus.com. 2009-02-18 . Получено 2012-09-07 .
  7. ^ "Новые структуры управления". Вики Tcler . Получено 21 августа 2020 г.
  8. ^ "страница руководства по повышению уровня". www.tcl.tk . Получено 21 августа 2020 г. .
  9. ^ "if manual page". www.tcl.tk . Получено 21 августа 2020 г. .
  10. ^ "If и if let выражения" . Получено 1 ноября 2020 г. .
  11. ^ "Американский национальный стандартный язык программирования FORTRAN". 1978-04-03. Архивировано из оригинала 2007-10-11 . Получено 2007-09-09 .
  12. ^ "VisualWorks: Conditional Processing". 2006-12-16. Архивировано из оригинала 2007-10-22 . Получено 2007-09-09 .
  13. ^ "Pythonic way to implement switch/case statements". Архивировано из оригинала 20.01.2015 . Получено 19.01.2015 .
  14. ^ Java.sun.com, Спецификация языка Java, 3-е издание.
  15. ^ Ecma-international.org Архивировано 12 апреля 2015 г. в спецификации языка Wayback Machine ECMAScript, 5-е издание.
  16. ^ "Соответствие образцу". Документация для Ruby 3.0 .

Внешние ссылки