Добрый день, сегодня без вступления. Почти
Функции
Если задуматься, что же такое функция, то можно понять, что это набор каких-то команд, который помещен в какую-то оболочку с названием. Что-то типа ребенка, которого вы научили выносить мусор. Вы вызываете у него функцию и он начинает выносить мусор. Если бы он не был научен и не знал набор инструкций, то вам бы пришлось каждый раз проводить его до мусорного бака, показывать куда выкидывать пакет, и как скрываться с места происшествия. То есть, как можно заметить, функция сокращает время и помогает мыслить более масштабно, используя (детишек!) уже более хитрые шаблоны достижения вашей цели. Давайте посмотрим, о чем я говорю. Представим, что вы внезапно захотели украсить свои математические и строковые тренировки разделителями с завитушками, ну примерно так (это означает, что вам сейчас опять придется открыть Main.as, удалить ваши предыдущие старания и написать вместо них следующие строки):
var x: Number = 20;
var y: Number = 10;
var z: Number = 30;
var text: String;
text = 'x=' + x + ', y=' + y + ', z=' + z;
trace(' ____________________________');
trace('/ \\');
trace('------------------------------');
trace('/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\');
trace(text);
trace('\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/');
trace('------------------------------');
trace('\\____________________________/');
Как видите, такой чизбургер занимает 8 строк кода, но на что не пойдешь ради завитушек! Итак, вы подумали, что можно проделать с вашими числами еще что-то. Например, вывести, сколько будет z * x, или x — y. И все в своем чизбургере, разумеется:
var x: Number = 20;
var y: Number = 10;
var z: Number = 30;
var text: String;
text = 'x=' + x + ', y=' + y + ', z=' + z;
trace(' ____________________________');
trace('/ \\');
trace('------------------------------');
trace('/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\');
trace(text);
trace('\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/');
trace('------------------------------');
trace('\\____________________________/');
text = 'z * x = ' + (z * x);
trace(' ____________________________');
trace('/ \\');
trace('------------------------------');
trace('/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\');
trace(text);
trace('\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/');
trace('------------------------------');
trace('\\____________________________/');
text = 'x - y = ' + (x - y);
trace(' ____________________________');
trace('/ \\');
trace('------------------------------');
trace('/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\');
trace(text);
trace('\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/');
trace('------------------------------');
trace('\\____________________________/');
Как видите, эта игра с чизбургерами начинает приобретать масштабы в коде. А все из-за того, что мы не знаем, что делать с одинаковыми повторяющимися вещами, которые занимают много строк. Для этого (для одинаковых повторяющихся вещей, что занимают много строк) и предназначены, как вы уже догадываетесь, функции. Давайте же посмотрим, что такое функция:
function cheeseburger() : void
{
}
Перед вами пустая функция с именем cheeseburger. Она полна таинства и увлекательности. Попробуем рассмотреть каждое слово и заодно символ. Первым в этой вещи идет слово function, оно почти как “var”, но только тут объявляется не переменная, а функция, которая сразу же несет в себе какое-то действие, в отличие от var, где можно объявить переменную, но ничего с ней не делать, а потом изменить. С функцией такого не прокатит. Следующим после слова function идет название самой функции, в нашем случае это cheeseburger. Затем идут открывающие и закрывающие скобки. Там идут входящие параметры, которые могут использоваться внутри функции, но если их нет, то можно и не писать. О них будет чуть позже, чтоб не нагружать вас сразу же. Далее идет двоеточие (прямо как в объявлении переменной), а после него идет тип функции. Как бы это не было странно, но у функции есть тоже тип. Только у функции это тип значения, которое вернет эта функция. Об этом будет тоже позже, чтоб вас не травмировать. Void обозначает, что функция ничего не возвращает, если что. Затем мы видим открывающую фигурную скобку, это обозначает, что после этой скобки вы можете писать всяческий код, который будет храниться в этой функции. Закрывающая скобка обозначает, как вы понимаете, окончание функции. Но спешу заметить, что тут существует иерархия фигурных скобок. То есть вы можете вложить в функцию еще одну функцию, но в таком случае, у нашей функции cheeseburger, окончанием будет уже вторая закрывающая фигурная скобка (потому что первая закрывающая скобка будет служить окончанием вложенной функции. Трудно понять, наверное, но на деле, если привыкнуть, все будет гораздо проще). Итак, мы разобрали нашу функцию по кусочкам и стоит закрепить витающие знания делом. Напишем в нашу функцию весь тот завитушечный сброд:
function cheeseburger() : void
{
trace(' ____________________________');
trace('/ \\');
trace('------------------------------');
trace('/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\');
trace(text);
trace('\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/');
trace('------------------------------');
trace('\\____________________________/');
}
Когда вы пишете что-то в функции, то обычно код в ней автоматически табулируется на одну табуляцию вправо. Такой подход помогает понять, что вы находитесь на каком-то уровне вложенности во что-то. Выглядит приятно, молодежно и стильно. Давайте теперь перепишем наш код по новой:
var x: Number = 20;
var y: Number = 10;
var z: Number = 30;
var text: String;
function cheeseburger() : void
{
trace(' ____________________________');
trace('/ \\');
trace('------------------------------');
trace('/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\');
trace(text);
trace('\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/');
trace('------------------------------');
trace('\\____________________________/');
}
text = 'x=' + x + ', y=' + y + ', z=' + z;
cheeseburger(); // мы вызвали функцию "чизбургер!".
// Очень схоже на trace(), не так ли? Так что же такое trace, в таком случае, ммм?
text = 'z * x = ' + (z * x);
cheeseburger();
text = 'x - y = ' + (x - y);
cheeseburger();
Как видите, теперь это коротко и ясно все, и занимает в 8 раз меньше места. Но внезапно нам захотелось выводить не только переменную text (она ведь у нас в функции cheeseburger трейсится) в завитушках, но и другие какие-нибудь вещи, например просто себе привет передать. Что для этого вы предпримете? Вполне может быть, разбили бы функцию на “верхняячасть чизбургера” и на “нижняя часть чизбургера”, и затем вызывали бы сначала верхнюю часть чизбургера, затем выводили бы ваше послание, а затем вызывали бы нижнюю часть чизбургера. Но это не торт, согласитесь. Давайте еще раз прочитаем строки, где говорилось о каких-то входящих параметрах. Так вот, у функции есть входящие параметры. Ей их можно создавать, если они необходимы, а можно и не создавать, если функция самодостаточна и ей никто не нужен. У нас функция была самодостаточной, пока нам внезапно не взбрело в голову что-то выводить еще там другое. Давайте же разбираться с входящими параметрами
Параметры у функции
Стоит вам рассказать об этом. У функции существуют входящие параметры. Они бываю двух типов: обязательные и необязательные. Что это такое? Сейчас объясню. Возьмем в пример функцию sayHello, и функцию sayHelloTo. Они будут выглядеть так:
function sayHello(name: String = '') : void
{
trace('Привет ' + name);
}
function sayHelloTo(name: String) : void
{
trace('Привет, ' + name);
}
Для начала стоит глянуть на то, что в скобках появились переменные какие-то. Это и есть входящие параметры. То есть, вызывая функцию, мы теперь можем указать ей какой-то параметр (в нашем случае, это строка), ну, типа sayHello(“Петька”);. Как можно заметить, эта переменная используется внутри функции, но хочу так же заявить, что дальше этой функции переменную использовать будет нельзя. В смысле, внутри этой функции переменная существует, но как функция выполнится, переменная исчезнет. Навсегда. Это еще называется локальной переменной, вот такие дела (по секрету, мы сейчас все в наших трудах пишем с помощью локальных переменных, и вы не поверите, но даже функции в данный момент локальные пишем (пока что), но это так, отступление). А теперь вам мимолетное задание: определить, в какой из этих двух функций используется обязательный параметр. Ответ строкой ниже
Правильный ответ: во второй. Во второй функции используется обязательный параметр. Объясняется это тем, что у нее параметр просто типа String, а в первом варианте он еще и автоматом заполняется (пустой строкой (две одинарные кавычки), но все же определен параметр). Итак, определительная черта обязательного параметра от необязательного в том, что обязательный параметр просто объявляется, а необязательный параметр объявляется, но еще и к нему вдобавок сразу же идет присвоение какого-то значения. Теперь стоит объяснить, в чем соль необязательных и обязательных параметров. Вы, скорее всего, и так уже догадываетесь, ведь вы и сами в жизни говорили не раз слово “не обязательно”. То есть, можно вписать, если хочется, а можно и оставить как есть. В этом-то и все отличие. Необязательный параметр обозначает, что обычно он используется почти всегда вот в таком варианте, но если надо, то все можно поменять. Так же хочу заметить, что если создать несколько параметров в одной функции, обязательных и не очень, то обязательные параметры должны идти в первую очередь, а после них, вконце, уже необязательные, иначе вас ждет ошибка. Вот, проверьте:
function getBall(type: String = 'футбольный', size: Number) : void
{
}
Вы получите такую ошибку: Error: Required parameters are not permitted after optional parameters.. Если же не вписать в функцию параметр, хотя он обязательный, вы получите такую ошибку: Error #1063: Несоответствие количества аргументов в Function/Main/private:init/getBall(). Ожидалось 1, получено 0.. То есть, оно ожидало параметр, а я обломал его, но за это и поплатился. Запомните эти ошибки, быстрее сможете понять, в чем проблема.
Наверное, вы уже и забыли, к чему я это все клоню, а клоню я к нашим старым добрым завитушкам. Давайте добавим в наш чизбургер обязательный параметр “stuffing” (вроде как начинкой переводится :), которую и будем высвечивать:
var x: Number = 20;
var y: Number = 10;
var z: Number = 30;
var text: String;
function cheeseburger(stuffing: String) : void
{
trace(' ____________________________');
trace('/ \\');
trace('------------------------------');
trace('/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\');
trace(stuffing);
trace('\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/');
trace('------------------------------');
trace('\\____________________________/');
}
text = 'x=' + x + ', y=' + y + ', z=' + z;
cheeseburger(text);
text = 'z * x = ' + (z * x);
cheeseburger('Невероятно, но факт: ' + text);
Как видите, это более приятно. Давайте попробуем теперь еще возвращать значение. Забудем о чизбургере, он умер. Теперь мы математики. И нам внезапно стало интересно, а что будет, если взять число (какое на ум пришло), прибавить к нему двойку, а затем умножить результат на 2, а затем прибавить тройку, а затем отнять задуманное число, а затем прибавить пятерку, а затем отнять тройку. Что же получится из этого? Поэтому вооружившись мелом и клавиатурой, мы решаем узнать наш мучающий нас вопрос (а заодно удалите все ваши предыдущие старания):
// мы будем работать только с целыми числами, поэтому
// и входящие и выходящие параметры будут целыми числами
// заметьте, что уже не void, а int на выходе
function solveProblem(num: int) : int
{
var result: int;
result = num + 2;
result = result * 2;
result += 3; // чтоб не писать result = result + 3
result -= num; // аналогично
result += 5;
result -= num;
return result; // внезапно какой-то return. Если перевести
// это слово на русский, то снанет понятно, что функция вернет
// куда-то наш результат. return используется для выхода из функции
// попутно возвращая какое-то значение. Для функций, что возвращают
// void, не нужно указывать, что возвращать, произойдет просто выход из функции
}
var num1: int = solveProblem(240);
var num2: int = solveProblem(1);
var num3: int = solveProblem(4);
trace(num1, num2, num3);
Мы получили ответы на интересующие нас вопросы: всегда выходит 12. Это все потому, что это математический фокус-покус *хохочет до слез*
Также, для пытливых умов, коорые “а как это так в трейс вмещаеся миллион переменных, хотя в подсказке видно только одну входящую переменную?”. Я вам скажу, это все из-за секретной комбинации “…rest”. Вернее, вообще троеточие перед названием переменной (в данном случае это rest). Но так как это массив, о котором в данной статье речи не пойдет, разбирайтесь сами, вот
Условия
Если можно подумать, что краткий экскурс в функции введен, то в условия не введен, что сейчас и будет исправляться. У меня есть подозрение, что вы уже подозреваете, что такое условие. “Не идешь со мной? Тогда я сам пошел”. Вот тут ставится условие, и еще и выполняется оно. Рассмотрим же, как это выглядит во флеше:
if(24 > 3)
{
trace('24 > 3');
}
Итак, что мы видим? На первой строчке пишется условие “if” и в скобках само условие (24 > 3). Затем выполняется (да-да, не зря я первым делом начал рассказывать про функции) что-то типа функции. Все ровно так же: открывающая скобка, закрывающая скобка. Как же это будет выглядеть “по-нашему”? Как-то типа этого:
если(24 > 3)
выполнить следующее
trace('24 > 3');
закончить выполнять
Также в условиях есть еще некое “а если нет, то тогда выполнить следующее”. Называется оно else
if(2 > 4)
{
trace('два больше четырех');
}
else
{
trace('два меньше четырех!');
}
При написании такой конструкции, мы увидим сообщение, что два меньше четырех, и это удивительно! Также существует еще else if. Это когда “если в магазине не будет белого хлеба, купи черный, если не будет и черного хлеба, тогда купи булочку, если даже булочки не будет, купи бублик, ну если даже бублика не будет, то выйди с казино/стрипклуба/кинотеатра и зайди в магазин”. Выглядит это так:
if(1 > 3)
{
trace('1 > 3');
}
else if (2 > 3)
{
trace('2 > 3');
}
else if (3 > 3)
{
trace('3 > 3');
}
else if (4 > 3)
{
trace('4 > 3');
}
Если порассуждать, то выполнится только последнее условие (и так и есть!). Если же вы, например, во втором условии “2 > 3″ двойку поменяете, например, на пятерку, то после того, как выполнится второе условие, проверяться третье и четвертое не будут. Какие же основные операторы сравнения? Сейчас расскажу самые основные:
> - больше (4 > 1) < - меньше (1 < 4) == - приравнивается (4 == 4) >= - больше или равно (4 >= 4) <= - меньше или равно (4 <= 4)
Запомните, что в условиях вы сравниваете числа только с помощью двух знаков равенства, если поставите один, вы произведете присваивание, чему мы учились в предыдущих статьях. Нельзя сравнивать, в общем, таким образом: “if(a=b)…”, нужно “if(a==b)…”
И да ИЛИ
Так как оператором “>=” было затронуто слово “ИЛИ”, то стоит вам рассказать о таких понятиях, как И и ИЛИ. И и ИЛИ это еще одни дополнительные возможности при выполнении условий. В фразе “больше ИЛИ равно” видно, что посиживает некая ИЛИ. Пишется она так: “||”. И же пишется так: “&&”. Что нам это дает? Дает нам это новый уровень “гибкости” при выполнении условий. Например если четыре больше двух и одновременно с этим меньше шести, то выполнить условие. Или же если два меньше четырех или два больше одного, то выполнить условие
var a: Number = 2;
var b: Number = 4;
var c: Number = 1;
if(a > b || a > c)
{
trace('"a" победила!');
}
if(a > b && a > c)
{
trace('"a" тотально победила!');
}
Если вы проверите, то выполнится только первое условие, потому что “2” больше только единицы, а во втором условии, требуется чтоб “a” была больше и “b” и “c”, но так как “b” равно четырем, то второе условие обломалось. Запомните или просто усвойте, а потом сами вспомните, когда пригодится это дело
Булево число
Что касается работы условий, то есть еще один секрет: они работают не за счет этих значков (утрировано), а за счет того, что выдают они — true или false. Условие выполняется, если выражение с этими операторами выдаст true, либо не выполняется, если выдаст false. Попробуйте, напишите в трейсе что-то типа
trace((1 > 4), (2 < 6), (6 >= 6));
Вы увидите false true true. А все потому, что единица меньше четырех, двойка меньше шести, а шесть равно или меньше шести. Как говорится, добро пожаловать в число Буля. Число буля крайне многогранно: либо 0, либо 1. В нашем случае, 0 это false, а true это 1. Во флеше это Boolean тип:
var bool1: Boolean = true;
var bool2: Boolean = (2 > 4);
trace(bool1, bool2);
if(bool1)
{
trace('true!');
}
Как вы понимаете, теперь набор операторов типа сравнения или неравенства стал еще шире, потому что вы можете, грубо говоря, выдумывать свои правила сравнения, написав функцию, которая будет возвращать булево число, сравнивая внутри себя ваши вещи по своим правилам, что избавит вас от гигантской строки сравнений внутри условия
На сим считаю статью закрытой. Краткий экскурс введен и туда и сюда. Теперь домашка:
Дано: детишки. Вам надо выяснить, кто умнее кого. Для этого я вам предлагаю создать функцию “compare”, у которой будут четыре входящих параметра: name1, iq1, name2, iq2. Это имена и айкью детишечек. В этой функции вы должны сравнить айкью, и вывести имя победителя или проигравшего. Внизу я приведу, как я буду вызывать функции и какие ответы ожидать:
compare("Петька", 90, "Максимка", 100); // Петька дурак
compare("Коля", 84, "Юрий", 82); // Юрий дурак
compare("Аполлоний", 100, "Афанасий", 100); // Победила дружба
Дерзайте. Спасибо за прочтение!
“Но внезапно нам захотелось выводить не только переменную text (она ведь у нас в функции cheeseburger трейсится) в завитушках, но и другие какие-нибудь вещи, например просто себе привет передать. Что для этого вы предпримете? Вполне может быть, разбили бы функцию на “верхняячасть чизбургера” и на “нижняя часть чизбургера”, и затем вызывали бы сначала верхнюю часть чизбургера, затем выводили бы ваше послание, а затем вызывали бы нижнюю часть чизбургера”
А зачем? Просто:
text = “привет себе”.
И работает без всякой разбивки чизбургера.
Like or Dislike:
0
0
Но ведь написано — “внезапно захотелось”, Анна :) Признаю, пример не самый воодушевляющий, но в нем главная суть — показать наличие входящих параметров, не более. А если уж ругаться надумали, то я смогу апеллировать тем, что потом эта функция сможет приобрести архиважный смысл, и тогда ее потом придется вынести в отдельный класс и сделать статичной, и тогда при обращении к переменной “text” она не будет работать, как минимум потому, что переменной text не будет вообще в том классе
Like or Dislike:
0
0
и да, спасибо, что следуете просьбе верхнего поста
Like or Dislike:
0
0
Спасибо за прекрасные уроки. Все так писали просто и понятно. Вам надо книги писать. Бестселлер был бы. Без подколов пишу. Просто уже достали всякие занудные Колины Муки и Машины потуги :)
Like or Dislike:
0
0
Все бы так писали, хотел сказать.)
Like or Dislike:
0
0