Анонімні функції дозволяють створити функції, в яких немає імені. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Анонімні функції дозволяють створити функції, в яких немає імені.



У контексті мов програмування під лямбда-функцією розуміють анонімну функцію. Тобто функцію, якій не зіставлено жодне ім'я, просто значення функціонального типа.

Анонімна функція – це оператор або вираз "inline", який можна використовувати кожного разу, коли очікується тип делегата. Її можна використовувати для ініціалізації іменованого делегата або підставити замість типу іменованого делегата як параметр методу.

Існує два типи анонімних функцій:

· Лямбда-вирази

· Анонімні методи

Лямбда-вираз — це анонімна функція, яка містить вирази і оператори і може використовуватися для створення делегатів або типів дерев виразів.

У всіх лямбда-виразах використовується лямбда-оператор =>, який читається як "переходить в". Ліва частина лямбда-оператора визначає параметри введення (якщо такі є), а права частина містить вираз або блок оператора.

Лямбда-вираз x => x * x читається як "x переходить в x x разів". Цей вираз може бути призначений типу делегата таким чином:

 

delegate int del(int i);

static void Main(string[] args)

{

del myDelegate = x => x * x;

int j = myDelegate(5); //j = 25

}

Оператор => має той самий пріоритет, що і оператор призначення (=) і є правоасоциативним.

Багато мов програмування підтримують роботу з анонімними функціями.

Приклади

С#

delegate(int x){return x +1; }

 

Pyton

lambda x: x + 1

 

Lisp

 

(lambda (x) (+ x 1))

 

 

PHP (http://blog.kron0s.com/anonymous-functions-in-php)

Змінні-функції

До того як сказати що-небудь про анонімні функції, поглянемо на концепцію PHP відому як змінні-функції. Вона полягає в тому, що якщо додати до змінної круглі дужки, то інтерпретатор PHP спочатку перевірить, чи не існує функції з ім'ям рівним значенню змінної і якщо вона є - виконати її. Це можна побачити на наступному прикладі:

 

  1. function Hello($name)
  2. {
  3. echo "Привіт $name";
  4. }

 

Ми можемо викликати цю функцію, використовуючи змінну, що зберігає її ім'я. І це може бути дуже корисно, якщо ім'я функції не визначене до моменту виконання.

 

  1. $func = "Hello";
  2. $func("Світ!");
  3. // результат:
  4. //Привіт, Світ!

Інший приклад, використовуючи клас і статичний метод:

 

  1. <?php
  2. class CHello
  3. {
  4. static function Hello($name)
  5. {
  6. echo "Привіт $name";
  7. }
  8. }
  9. $func = "Hello";
  10. CHello::$func("Світ!");
  11. // результат:
  12. // Привіт, світ!
  13. ?>

 

Анонімні або лямбда функції в php

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

Розглянемо на прикладі:

 

1. <?php

2. $str = "Привіт, Світ!";

3. $lambda = create_function('$match', 'return "Друг!";');

4. $str = preg_replace_callback('/Мир/' $lambda, $str);

5. echo $str;

6. ?>

Тут ми створили маленьку безіменну (анонімну) функцію, яка викликається у функції preg_replace_callback. Хоча create_function дозволяє створити анонімні функції, це не частина мови, а "хак". PHP 5.3 підтримує по справжньому анонімні функції як частину мови. Ми створюємо безіменну функцію і призначаємо її змінній і потім просто використовуємо цю змінну як функцію.

Приклад:

1. <?php

2. $func = function($name)

3. {

4. echo "Привіт $name\n";

5. };

6.

7. $func("Світ!");

8. $func("Олексій!");

9.

10. // результат:

11. //Привіт, Світ!

12. //Привіт, Олексій!

13. ?>

 

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

1. <?php

2. $str = "Привіт, Світ!";

3. $func = function($match)

4. {

5. return "друг!";

6. };

7.

8. $str = preg_replace_callback('/Мир/' $func, $str);

9. echo $str;

10. ?>

 

Анонімні і вкладені функції

PHP дозволяє вкладати функції всередину одна одної. Розглянемо на прикладі. Функція censorString приймає рядок як параметр і замінює потрібні слова в рядку на "*". Функція censorString визначає вкладену функцію replace, яка використовується при виклику preg_replace_callback. Враховуючи те, що функція replace використовується в нашій програмі лише у функції censorString, краще всього визначити її як вкладену, аби не забруднювати простір імен.

 

1. <?php

2. function censorString($string, $censor)

3. {

4. function replace($match)

5. {

6. return str_repeat("*", strlen($match[0]));

7. }

8.

9. return preg_replace_callback('/'.$censor.'/', 'replace' $string);

10.

11. }

12.

13. echo censorString("Привіт, світ!", "світ");

14. echo censorString("Привіт, світ!", "Привіт");

15.

16. // результат:

17. // Привіт ***!

18. // Fatal error: Cannot redeclare replace()

19. ?>

20.

 

При такому визначенні функції як в прикладі вище, вкладена функція не існує до тих пір, поки не почнеться виконуватися батьківська функція. Як тільки виконується батьківська функція (censorString), вкладена функція з'являється в глобальному просторі імен. Тепер ми можемо дістати доступ до вкладеної функції з будь-якого місця програми. Проблема полягає в тому, що при повторному виклику батьківської функції буде зроблена спроба передекларувати вкладену функцію, що викличе помилку, оскільки вона вже існує. Рішення в тому, аби використовувати вкладену функцію, як це показано нижче. (Зверніть увагу на крапку з комою в кінці вкладеної функції.)

 

1. <?php

2. function censorString($string, $censor)

3. {

4. $func = function($match)

5. {

6. return str_repeat("*", strlen($match[0]));

7. };

8.

9. return preg_replace_callback('/'.$censor.'/', $func, $string);

10.

11. }

12.

13. echo censorString("Привіт, світ!", "світ");

14. echo censorString("Привіт світ!", "Привіт");

15.

16. // результат:

17. // Привіт ***!

18. // ******, світ!

19. ?>

Тепер вкладена функція з'являється лише на час виконання censorString. Отже, ми можемо повторно викликати функцію censorString без того, аби викликати помилку передекларації.

 

Інший спосіб визначити вкладену функцію:

1. <?php

2. function censorString($string, $censor)

3. {

4.

5. return preg_replace_callback('/'.$censor.'/',

6. function($match)

7. {

8. return str_repeat("*"

9. strlen($match[0]));

10. },

11. $string);

12.

13. }

14.

15. echo censorString("Привіт, світ!", "світ");

16. echo censorString("Привіт, світ!", "Привіт");

17.

18. // результат:

19. // Привіт ***!

20. // ******, світ!

21. ?>

Замикання

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

1. <?php

2. $mult = function($x)

3. {

4. return $x * 5;

5. };

6.

7. echo $mult(2);

8.

9. // результат:

10. // 10

11. ?>

 

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

1. <?php

2. $multiply = function($multiplier)

3. {

4. return function($x) use ($multiplier)

5. {

6. return $x * $multiplier;

7. };

8. };

9.

10. // $mul5 тепер містить функцію, яка умножає аргумент на п'ять

11. $mult5 = $multiply(5);

12.

13. // $mul7 тепер містить функцію, яка умножає аргумент на сім

14. $mult7 = $multiply(7);

15.

16. echo $mult5(5);

17. echo $mult7(5);

18.

19. // результат:

20. // 25

21. // 35

22. ?>

 



Поделиться:


Последнее изменение этой страницы: 2017-02-21; просмотров: 280; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.133.144.197 (0.018 с.)