Pregunta

Nunca he usado funciones anidadas, pero he visto referencias a ellos en varios idiomas (además de clases anidadas, que supongo están relacionados).

  • ¿Qué es una función anidada?
  • ¿Por qué?!?
  • ¿Qué se puede hacer con una función anidada que no se puede hacer de otra manera?
  • ¿Qué se puede hacer con una función anidada esto es difícil o poco elegante sin funciones anidadas?

Asumo funciones anidadas son simplemente un artefacto de tratar todo como un objeto, y si los objetos pueden contener otros objetos entonces se sigue.

Haga funciones anidadas tienen alcance (en general, supongo que las lenguas difieren en esto) al igual que las variables dentro de una función tienen alcance?

Por favor, añadir el idioma se hace referencia a si no está seguro de que su respuesta es el lenguaje agnóstico.

-Adán

¿Fue útil?

Solución

Un uso popular de funciones anidadas es cierres . En una ámbito léxico lenguaje con funciones de primera clase es posible utilizar funciones para almacenar datos. Un simple ejemplo en el Esquema es un contador:

(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

En este ejemplo, el contador nido función dentro de la función de marca de venta libre, y devolviendo esta función interna que son capaces de acceder a los datos disponibles para contrarrestar cuando se definió. Esta información es privada para esta instancia de MyCounter - si tuviéramos que crear otro contador, sería utilizar un lugar diferente para almacenar la cuenta interna. Siguiendo con el ejemplo anterior:

(define mycounter2 (make-counter))

(mycounter2)                      ; returns 1

(mycounter)                       ; returns 3

Otros consejos

Es útil para la recursividad cuando sólo hay 1 método que jamás se llaman

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

El código anterior es hecha completamente, pero se basa en C # para dar la idea de lo que quiero decir. El único método que se puede llamar NestedGetFiles es el método GetFiles.

Una función anidada es sólo una función dentro de otra función.

Sí, es consecuencia de que todo es un objeto. Ya que se puede tener variables pueden ser vistos en el alcance de la función y las variables puede apuntar a las funciones que puede tener una función que hace referencia a una variable local.

No creo que hay algo que se puede hacer con una función anidada que a pesar de todo no se podía prescindir. Muchas de las veces tiene sentido, sin embargo. A saber, cuando una función es un "sub-función" de alguna otra función.

Un caso de uso común para mí es cuando una función realiza una gran cantidad de lógica complicado, pero lo que la función calcula / devoluciones es fácil abstracta para todos los casos dictadas por la lógica.

(C #): Yo uso eso para simplificar la vista Explorador de objetos, y para estructurar mejor a mis clases. Como la rueda de clase anidada en la clase de camiones.

No se olvide este detalle: "Tipos anidados pueden tener acceso a los miembros privados y protegido del tipo que contiene, incluidos los miembros privados o protegidos heredados."

Funciones anidadas le permiten encapsular código que sólo es relevante para el funcionamiento interno de una función dentro de esa función, al tiempo que permite a separar ese código a cabo para facilitar la lectura o la generalización. En algunas implementaciones, sino que también permiten el acceso al ámbito exterior. En 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();
    }
}

Por supuesto, en este caso, esto podría también ser manejado con RAII, pero es sólo un ejemplo sencillo.

También puede ser útil si usted necesita para pasar de una función a otra función como argumento. También pueden ser útiles para hacer las funciones de fábrica para las funciones de fábrica (en Python):

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

Una función anidada es simplemente una función definida dentro del cuerpo de otra función. ¿Por qué? Sobre la única razón por la que podía pensar en la parte superior de mi cabeza es una función auxiliar o utilidad.

Este es un ejemplo artificioso pero hay que tener conmigo. Vamos a decir que tenía una función que tenía que actuar sobre los resultados de dos consultas y rellenar un objeto con los valores de una de las consultas. Se podría hacer algo como lo siguiente.

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;

}

Si tienes 20 propiedades, que está duplicando el código para establecer el objeto una y otra vez conduce a una función enorme. Se podría añadir una función anidada simple de hacer la copia de las propiedades de la consulta al objeto. De esta manera:

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


}

Mantiene las cosas un poco más limpio. ¿Tiene que ser una función anidada? No, pero es posible que desee hacerlo de esta manera, si la función de proceso es el único que tendría que hacer esta copia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top