什么是嵌套函数? 它们是做什么用的?

发布于 2024-07-13 16:33:58 字数 348 浏览 10 评论 0原文

我从未使用过嵌套函数,但在多种语言中看到过对它们的引用(以及嵌套类,我认为它们是相关的)。

  • 什么是嵌套函数?
  • 为什么?!?
  • 你可以用嵌套函数做哪些其他方法无法做的事情?
  • 你能用嵌套函数做什么,如果没有嵌套函数,这会很困难或不优雅?

我认为嵌套函数只是将所有内容视为对象的产物,如果对象可以包含其他对象,那么它就会随之而来。

嵌套函数是否具有作用域(一般来说,我认为语言在这方面有所不同),就像函数内的变量具有作用域一样吗?

如果您不确定您的答案是否与语言无关,请添加您所引用的语言。

-亚当

I've never used nested functions, but have seen references to them in several languages (as well as nested classes, which I assume are related).

  • What is a nested function?
  • Why?!?
  • What can you do with a nested function that you cannot do any other way?
  • What can you do with a nested function this is difficult or inelegant without nested functions?

I assume nested functions are simply an artifact of treating everything as an object, and if objects can contain other objects then it follows.

Do nested functions have scope (in general, I suppose languages differ on this) just as variables inside a function have scope?

Please add the language you are referencing if you're not certain that your answer is language agnostic.

-Adam

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

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

发布评论

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

评论(7

美胚控场 2024-07-20 16:33:58

嵌套函数的一种流行用法是闭包。 在具有一流函数的词法作用域语言中,它是可以使用函数来存储数据。 Scheme 中的一个简单示例是计数器:

(define (make-counter)
  (let ((count 0))                ; used to store the count
    (define (counter)             ; this is the counter we're creating
      (set! count (+ count 1))    ; increment the count
      count)                      ; return the new count
    counter))                     ; return the new counter function

(define mycounter (make-counter)) ; create a counter called mycounter

(mycounter)                       ; returns 1

(mycounter)                       ; returns 2

在这个示例中,我们将函数计数器嵌套在函数 make-counter 中,通过返回此内部函数,我们可以访问定义计数器时可用于计数器的数据。 此信息对于 mycounter 的此实例是私有的 - 如果我们要创建另一个计数器,它将使用不同的位置来存储内部计数。 继续前面的示例:

(define mycounter2 (make-counter))

(mycounter2)                      ; returns 1

(mycounter)                       ; returns 3

One popular use of nested functions is closures. In a lexically scoped language with first-class functions it's possible to use functions to store data. A simple example in Scheme is a counter:

(define (make-counter)
  (let ((count 0))                ; used to store the count
    (define (counter)             ; this is the counter we're creating
      (set! count (+ count 1))    ; increment the count
      count)                      ; return the new count
    counter))                     ; return the new counter function

(define mycounter (make-counter)) ; create a counter called mycounter

(mycounter)                       ; returns 1

(mycounter)                       ; returns 2

In this example, we nest the function counter inside the function make-counter, and by returning this internal function we are able to access the data available to counter when it was defined. This information is private to this instance of mycounter - if we were to create another counter, it would use a different spot to store the internal count. Continuing from the previous example:

(define mycounter2 (make-counter))

(mycounter2)                      ; returns 1

(mycounter)                       ; returns 3
寄离 2024-07-20 16:33:58

当只有 1 个方法调用递归时,它对递归很有用。

string[] GetFiles(string path)
{
  void NestedGetFiles(string path, List<string> result)
  {
    result.AddRange( files in the current path);
    foreach(string subPath in FoldersInTheCurrentPath)
      NestedGetFiles(subPath, result);
  }

   List<string> result = new List<string>();
   NestedGetFiles(path, result);
   return result.ToArray();
}

上面的代码完全是编写的,但基于 C# 来表达我的意思。 唯一可以调用 NestedGetFiles 的方法是 GetFiles 方法。

It's useful for recursion when there is only 1 method that will ever call it

string[] GetFiles(string path)
{
  void NestedGetFiles(string path, List<string> result)
  {
    result.AddRange( files in the current path);
    foreach(string subPath in FoldersInTheCurrentPath)
      NestedGetFiles(subPath, result);
  }

   List<string> result = new List<string>();
   NestedGetFiles(path, result);
   return result.ToArray();
}

The above code is completely made up but is based on C# to give the idea of what I mean. The only method that can call NestedGetFiles is the GetFiles method.

你在我安 2024-07-20 16:33:58

嵌套函数允许您封装仅与一个函数的内部工作相关的代码,同时仍然允许您将该代码分离出来以提高可读性或通用性。 在某些实现中,它们还允许访问外部范围。 In D:

int doStuff() {
    int result;
    void cleanUpReturn() {
        myResource1.release();
        myResource2.release();
        return result * 2 + 1;
    }

    auto myResource1 = getSomeResource();
    auto myResource2 = getSomeOtherResource();
    if(someCondition) {
        return cleanUpReturn();
    } else {
        doSomeOtherStuff();
        return cleanUpReturn();
    }
}

当然,这种情况也可以用RAII来处理,但这只是一个简单的例子。

Nested functions allow you to encapsulate code that is only relevant to the inner workings of one function within that function, while still allowing you to separate that code out for readability or generalization. In some implementations, they also allow access to outer scope. In D:

int doStuff() {
    int result;
    void cleanUpReturn() {
        myResource1.release();
        myResource2.release();
        return result * 2 + 1;
    }

    auto myResource1 = getSomeResource();
    auto myResource2 = getSomeOtherResource();
    if(someCondition) {
        return cleanUpReturn();
    } else {
        doSomeOtherStuff();
        return cleanUpReturn();
    }
}

Of course, in this case this could also be handled with RAII, but it's just a simple example.

上课铃就是安魂曲 2024-07-20 16:33:58

嵌套函数只是在另一个函数体内定义的函数。 为什么? 我能立即想到的唯一原因是辅助函数或实用函数。

这是一个人为的例子,但请耐心等待。 假设您有一个函数,必须对两个查询的结果进行操作,并使用其中一个查询的值填充对象。 你可以做类似下面的事情。

function process(qryResult q1, qryResult q2) {

   object o;
   if (q1.someprop == "useme") {
       o.prop1 = q1.prop1;
       o.prop2 = q1.prop2;
       o.prop3 = q1.prop3;
   } else if (q2.someprop == "useme") {
       o.prop1 = q2.prop1;
       o.prop2 = q2.prop2;
       o.prop3 = q2.prop3;
   }

   return o;

}

如果您有 20 个属性,则需要重复代码来一遍又一遍地设置对象,从而导致一个巨大的函数。 您可以添加一个简单的嵌套函数来将属性从查询复制到对象。 就像这样:

function process(qryResult q1, qryResult q2) {

   object o;
   if (q1.someprop == "useme") {
       fillObject(o,q1);
   } else if (q2.someprop == "useme") {
       fillObject(o,q2);
   }

   return o;

   function fillObject(object o, qryResult q) {
       o.prop1 = q.prop1;
       o.prop2 = q.prop2;
       o.prop3 = q.prop3;
   }


}

它让事情变得更干净。 它必须是嵌套函数吗? 不,但如果 process 函数是唯一需要执行此复制的函数,您可能希望采用这种方式。

A nested function is simply a function defined within the body of another function. Why? About the only reason I could think of off the top of my head is a helper or utility function.

This is a contrived example but bear with me. Let's say you had a function that had to act on the results two queries and fill an object with values from one of the queries. You could do something like the following.

function process(qryResult q1, qryResult q2) {

   object o;
   if (q1.someprop == "useme") {
       o.prop1 = q1.prop1;
       o.prop2 = q1.prop2;
       o.prop3 = q1.prop3;
   } else if (q2.someprop == "useme") {
       o.prop1 = q2.prop1;
       o.prop2 = q2.prop2;
       o.prop3 = q2.prop3;
   }

   return o;

}

If you had 20 properties, you're duplicating the code to set the object over and over leading to a huge function. You could add a simple nested function to do the copy of the properties from the query to the object. Like this:

function process(qryResult q1, qryResult q2) {

   object o;
   if (q1.someprop == "useme") {
       fillObject(o,q1);
   } else if (q2.someprop == "useme") {
       fillObject(o,q2);
   }

   return o;

   function fillObject(object o, qryResult q) {
       o.prop1 = q.prop1;
       o.prop2 = q.prop2;
       o.prop3 = q.prop3;
   }


}

It keeps things a little cleaner. Does it have to be a nested function? No, but you may want to do it this way if the process function is the only one that would have to do this copy.

一念一轮回 2024-07-20 16:33:58

(C#) :
我用它来简化对象浏览器视图,并更好地构建我的类。
作为 Wheel 类嵌套在 Truck 类中。

不要忘记这个细节:
“嵌套类型可以访问包含类型的私有和受保护成员,包括任何继承的私有或受保护成员。”

(C#) :
I use that to simplify the Object Browser view, and to structure my classes better.
As class Wheel nested in Truck class.

Don't forget this detail :
"Nested types can access private and protected members of the containing type, including any inherited private or protected members."

∝单色的世界 2024-07-20 16:33:58

如果您需要将一个函数作为参数传递给另一个函数,它们也很有用。 它们对于为工厂函数创建工厂函数也很有用(在 Python 中):

>>> def GetIntMaker(x):
...   def GetInt():
...     return x
...   return GetInt
... 
>>> GetInt = GetIntMaker(1)
>>> GetInt()
1

They can also be useful if you need to pass a function to another function as an argument. They can also be useful for making factory functions for factory functions (in Python):

>>> def GetIntMaker(x):
...   def GetInt():
...     return x
...   return GetInt
... 
>>> GetInt = GetIntMaker(1)
>>> GetInt()
1
不寐倦长更 2024-07-20 16:33:58

嵌套函数只是另一个函数内部的一个函数。

是的,这是一切事物都是对象的结果。 由于您可以拥有仅在函数范围内可见的变量,并且变量可以指向函数,因此您可以拥有由局部变量引用的函数。

我不认为使用嵌套函数可以做任何你绝对不能做的事情。 不过很多时候这是有道理的。 即,每当一个函数是某个其他函数的“子函数”时。

对我来说,一个常见的用例是,一个函数执行大量复杂的逻辑,但该函数计算/返回的内容很容易抽象为该逻辑规定的所有情况。

A nested function is just a function inside another function.

Yes, it is a result of everything being an object. Since you can have variables only visible in the function's scope and variables can point to functions you can have a function that is referenced by a local variable.

I don't think there is anything that you can do with a nested function that you absolutely couldn't do without. A lot of the times it makes sense, though. Namely, whenever a function is a "sub-function" of some other function.

A common use-case for me is when a function performs a lot of complicated logic but what the function computes/returns is easy to abstract for all the cases dictated by the logic.

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