匿名函数到底是什么?

发布于 2024-11-03 02:23:28 字数 202 浏览 4 评论 0原文

在我的一千行 Ruby 之旅中,我对匿名函数的概念感到非常困难。维基百科说了一些关于代码中存在一些无名的灵魂,并且它服从更高的命令,但是我的理解到此为止。

或者换句话说,我(当我理解它时)如何向我妈妈解释匿名函数?

In my journey of a thousand lines of Ruby, I'm having a really hard time with the concept of anonymous functions. Wikipedia says something about there being some nameless soul in the code and it submitting to a higher order, but my understanding ends there.

Or in other words, how would I (when I understand it) explain anonymous functions to my mom?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

浅听莫相离 2024-11-10 02:23:28

匿名函数具有以下特征:

  1. 它没有名称(因此是匿名的)
  2. 是内联定义的
  3. 当您不希望普通函数的开销/形式时使用
  4. 不会多次显式引用,除非作为参数传递给另一个函数

An anonymous function has these characteristics:

  1. It has no name (hence anonymous)
  2. Is defined inline
  3. Used when you don't want the overhead/formality of a normal function
  4. Is not explicitly referenced more than once, unless passed as an argument to another function
夢归不見 2024-11-10 02:23:28

下面是 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 中甚至有一种语法用于将 lambda 作为单个受祝福的块传递:

print_it = lambda{ |item| puts item }
%w[a b c].each(&print_it)
#=> a
#=> b
#=> c

...但您也可以将 lambda 作为普通参数传递并稍后调用它,如下所示:

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

Here's one example of an anonymous function in Ruby (called a block in this case):

my_array.each{ |item| puts item }

Where's the anonymous function in the above? Why, it's the one that receives a single parameter, names it 'item', and then prints it. In JavaScript, the above might be written as...

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); });

...which both makes it a little bit more clear that a function is being passed as an argument, and also helps one appreciate Ruby's syntax. :)

Here's another anonymous function (back in 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!

Although the example is obviously contrived, it shows how you can create a new function (in this case named count) and assign it to a variable, and use that for recursive calls inside a master method. (Some feel that this is better than creating a second method just for the recursion, or re-using the master method for recursion with very different parameters.)

The function doesn't have a name, the variable does. You could assign it to any number of variables, all with different names.

Returning to the first example, there's even a syntax in Ruby for passing a lambda as the single, blessed block:

print_it = lambda{ |item| puts item }
%w[a b c].each(&print_it)
#=> a
#=> b
#=> c

...but you can also pass a lambda as a normal parameter and call it later, as illustrated here:

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
远昼 2024-11-10 02:23:28

除了之前的答案之外,当您使用闭包时,匿名函数非常有用:

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

In addiction to previous answers, the anonymous functions are very usefull when you working with closures:

def make_adder n
  lambda { |x|
    x + n
  }
end

t = make_adder 100
puts t.call 1

Or (in 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
写给空气的情书 2024-11-10 02:23:28

正如维基百科所说:一个没有名字的函数。

这意味着您无法通过使用函数的名称和参数以典型方式调用该函数。相反,函数本身通常是另一个函数的参数。对函数进行运算的函数称为“高阶函数”。

考虑这个 JavaScript(我知道您标记了这个 ruby​​,但是...):

  window.onload=function(){
           //some code here
  }

该函数将在页面加载时执行,但您不能通过名称调用它,因为它没有名称。

Just as Wikipedia says: a function with no name.

It means that you cannot invoke the function in the typical way, by using its name and parameters. Rather the function itself is usually a parameter to another function. A function that operates on functions is called a "higher order function".

Consider this JavaScript(I know you tagged this ruby but...):

  window.onload=function(){
           //some code here
  }

The function will execute when the page loads, but you cannot invoke it by name, because it does not have a name.

多彩岁月 2024-11-10 02:23:28

匿名方法有什么意义?

类比解释:

当我订购我最喜欢的汉堡(油腻的 Big Nac)时,我不想花 5 分钟填写正式的订购申请:姓名、地址、电话号码等。我没有时间这样做。我想用我的嘴:“给我一个汉堡”,又好又快又简单。

匿名方法有点像同一件事,除了编码时:

它有点像一次性方法,可以让您更快地编码

它在编码时是一样的。如果你必须定义一个函数,你必须把它放在某个地方(其他地方),你必须给它起个名字,这是一种痛苦,特别是如果你知道你永远不会再需要它。当您阅读代码时,您可能必须使用复杂的 IDE 才能再次找到该方法以及对它的引用。多么痛苦啊!您需要一种一次性方法,可以直接在代码中编写需要的地方,然后完成它,然后移动一个。匿名方法解决了这个特殊问题。

What is the point of an anonymous method?

Explanation by Analogy:

When I order my favourite burger (a greasy Big Nac), I don't want to spend 5 minutes filling out a formal order application: name, address, phone number etc. I ain't got time for that. I want to use my mouth: "give me a burger", nice and quick and easy.

Anonymous methods are kinda like the same thing, except when coding:

It's kinda like throwaway method allowing you to code faster

It's the same when coding. If you have to define a function, you have to put it somewhere (else), you have to call it something, and that's a pain, especially if you know you'll never, ever need it again. And when you read the code, you might have to use a complicated IDE to find that method again, and a reference to it. What a pain! You need a throwaway method that you can write directly in your code, where you need it, and just get it done, and move one. Anonymous methods solve this particular problem.

再浓的妆也掩不了殇 2024-11-10 02:23:28

匿名函数具有以下特点:

  • 无名称
  • 内联声明
  • 声明时直接执行

Anonymous functions have the following characteristics:

  • No name
  • Inline declaration
  • Executed directly when declared
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文