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

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

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

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

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

-亚当

有帮助吗?

解决方案

嵌套函数的一种流行用法是 关闭. 。在一个 词法范围 具有一流函数的语言可以使用函数来存储数据。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

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

(define mycounter2 (make-counter))

(mycounter2)                      ; returns 1

(mycounter)                       ; returns 3

其他提示

当只有 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 方法。

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

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

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

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

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

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

嵌套函数允许您封装仅与一个函数的内部工作相关的代码,同时仍然允许您将该代码分离出来以提高可读性或通用性。在某些实现中,它们还允许访问外部范围。在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 来处理,但这只是一个简单的例子。

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

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

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

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

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 函数是唯一需要执行此复制的函数,您可能希望采用这种方式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top