Pergunta

Eu nunca usei funções aninhadas, mas vi referências a eles em várias línguas (assim como classes aninhadas, que eu suponho que estão relacionados).

  • O que é uma função aninhada?
  • Por que?!?
  • O que você pode fazer com uma função aninhada que você não pode fazer de outra maneira?
  • O que você pode fazer com uma função aninhada isso é difícil ou deselegante, sem funções aninhadas?

Eu assumo funções aninhadas são simplesmente um artefato de tratar tudo como um objeto, e se os objetos podem conter outros objetos, em seguida, segue-se.

Do funções aninhadas têm escopo (em geral, acho que as línguas diferem sobre isso), assim como variáveis ??dentro de uma função têm escopo?

Por favor, adicione o idioma que você está fazendo referência se você não está certo de que a sua resposta é agnóstico linguagem.

-Adam

Foi útil?

Solução

Um uso popular de funções aninhadas é fechamentos . Em um escopo léxico linguagem com funções de primeira classe é possível utilizar as funções para armazenar dados. Um exemplo simples no Esquema é um 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

Neste exemplo, nós ninho do balcão função dentro da função make-counter, e devolvendo essa função interna somos capazes de acessar os dados disponíveis para contador quando ele foi definido. Esta informação é privada para esta instância do mycounter - se tivéssemos de criar um outro balcão, seria usar um local diferente para armazenar a contagem interna. Continuando a partir do exemplo anterior:

(define mycounter2 (make-counter))

(mycounter2)                      ; returns 1

(mycounter)                       ; returns 3

Outras dicas

É útil para recursão quando há apenas 1 método que nunca vai chamá-lo

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

O código acima está completamente formado, mas é baseado em C # para dar a ideia do que quero dizer. O único método que pode chamar NestedGetFiles é o método GetFiles.

A função aninhada é apenas uma função dentro de outra função.

Sim, é um resultado de tudo ser um objeto. Desde que você pode ter variáveis ??visível apenas no escopo da função e variáveis ??podem apontar para funções que você pode ter uma função que é referenciado por uma variável local.

Eu não acho que há alguma coisa que você pode fazer com uma função aninhada que você absolutamente não pode prescindir. Um monte de vezes, faz sentido, no entanto. Ou seja, sempre que uma função é um "sub-função" de alguma outra função.

Um caso de uso comum para mim é quando uma função executa um monte de lógica complicado, mas o que a função calcula / retornos é fácil de abstrato para todos os casos ditadas pela lógica.

(C #): Eu uso isso para simplificar a tela Browser Object, e estruturar as minhas aulas melhor. Como Roda classe aninhada na classe Truck.

Não se esqueça deste detalhe: "Tipos aninhados pode acessar membros privados e protegidos do tipo que contém, incluindo os membros privada ou protegida herdadas."

funções aninhadas permitem código de encapsular que só é relevante para o funcionamento interno de uma função dentro dessa função, enquanto ainda permitindo que você separe esse código para fora para facilitar a leitura ou generalização. Em algumas implementações, eles também permitem o acesso ao espaço exterior. Em 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();
    }
}

É claro que, neste caso, isso poderia também ser manuseados com RAII, mas é apenas um exemplo simples.

Eles também pode ser útil se você precisa para passar uma função para outra função como um argumento. Eles também pode ser útil para fazer funções de fábrica para funções de fábrica (em Python):

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

Uma função aninhada é simplesmente uma função definida dentro do corpo de uma outra função. Por quê? Sobre a única razão que eu poderia pensar em cima da minha cabeça é uma função auxiliar ou utilidade.

Este é um exemplo inventado, mas urso comigo. Vamos dizer que você tinha uma função que tinha que agir sobre os resultados duas consultas e preencher um objeto com valores a partir de uma das consultas. Você poderia fazer algo como o seguinte.

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;

}

Se você tivesse 20 propriedades, você está duplicando o código para definir o objeto mais e mais levando a uma enorme função. Você pode adicionar uma função aninhada simples de fazer a cópia das propriedades da consulta para o objeto. Como esta:

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


}

Ele mantém as coisas um pouco mais limpo. Tem que ser uma função aninhada? Não, mas você pode querer fazê-lo desta forma, se a função de processo é o único que teria que fazer essa cópia.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top