Что такое анонимные функции?
В моем путешествии по тысячам строк Ruby мне очень сложно с концепцией анонимных функций. Wikipedia говорит что-то о, в которой есть какая-то безымянная душа в коде, и она подчиняется более высокому порядку, но мое понимание заканчивается на этом.
Или, другими словами, как я (когда я это понимаю) объясню анонимные функции моей маме?
Ответы
Ответ 1
Анонимная функция имеет следующие характеристики:
- У него нет имени (следовательно, анонимного)
- Определяется встроенным
- Используется, когда вам не нужны служебные/формальные функции нормальной функции
- Явным образом не упоминается более одного раза, если не передано в качестве аргумента другой функции
Ответ 2
Вот один пример анонимной функции в Ruby (называемый в данном случае блоком):
my_array.each{ |item| puts item }
Где анонимная функция в приведенном выше? Почему, тот, который получает единственный параметр, называет его "item", а затем печатает его. В JavaScript вышеуказанное может быть написано как...
Array.prototype.each = function(anon){
for (var i=0,len=this.length;i<len;++i) anon(this[i]);
};
myArray.each(function(item){ console.log(item); });
..., который делает несколько более понятным, что функция передается как аргумент, а также помогает оценить синтаксис Ruby.:)
Здесь другая анонимная функция (назад в Ruby):
def count_to(n)
puts "I'm going to count to #{n}"
count = lambda do |i|
if (i>0)
count[i-1]
puts i
end
end
count[n]
puts "I'm done counting!"
end
count_to(3)
#=> I'm going to count to 3
#=> 1
#=> 2
#=> 3
#=> I'm done counting!
Хотя этот пример явно надуман, он показывает, как вы можете создать новую функцию (в этом случае с именем count) и назначить ее переменной, и использовать ее для рекурсивных вызовов внутри основного метода. (Некоторые считают, что это лучше, чем создание второго метода только для рекурсии или повторного использования главного метода для рекурсии с очень разными параметрами.)
Функция не имеет имени, переменная делает. Вы можете назначить его любому числу переменных, все с разными именами.
Возвращаясь к первому примеру, существует даже синтаксис в Ruby для передачи лямбда в качестве единственного, благословенного блока:
print_it = lambda{ |item| puts item }
%w[a b c].each(&print_it)
#=> a
#=> b
#=> c
... но вы также можете передать лямбду в качестве нормального параметра и вызвать ее позже, как показано здесь:
module Enumerable
def do_both_to_each( f1, f2 )
each do |item|
f1[item]
f2[item]
end
end
end
print_prefix = lambda{ |i| print "#{i}*#{i} -> " }
print_squared = lambda{ |i| puts i*i }
(1..4).do_both_to_each(print_prefix,print_squared)
#=> 1*1 -> 1
#=> 2*2 -> 4
#=> 3*3 -> 9
#=> 4*4 -> 16
Ответ 3
В зависимости от предыдущих ответов анонимные функции очень полезны, когда вы работаете с закрывает:
def make_adder n
lambda { |x|
x + n
}
end
t = make_adder 100
puts t.call 1
Или (в Ruby 1.9):
def make_adder_1_9 n
->(x) {
x + n
}
end
t_1_9 = make_adder_1_9 100
puts t_1_9.call 1
Ответ 4
Так же, как Wikipedia говорит: функция без имени.
Это означает, что вы не можете вызвать функцию обычным способом, используя ее имя и параметры. Скорее, сама функция обычно является параметром для другой функции. Функция, которая работает с функциями, называется "функцией более высокого порядка".
Рассмотрим этот JavaScript (я знаю, что вы отметили этот рубин, но...):
window.onload=function(){
//some code here
}
Функция будет выполняться при загрузке страницы, но вы не можете ее вызывать по имени, потому что у нее нет имени.