Wie ruft man eine Funktion in sich auf?

7

Ich habe eine Funktion, die einen Schlüssel aus 4 Zeichen generiert, der für jedes Mal eindeutig sein muss. Um dies zu tun, generiert die Funktion zuerst einen Schlüssel und überprüft dann eine Datenbanktabelle, um zu sehen, ob sie von jemand anderem verwendet wird.

Wenn es nicht verwendet wird, gibt es den Schlüssel zurück, sonst ruft es sich selbst erneut auf, aber das bewirkt, dass die Funktion eine Endlosschleife ausführt, die ein Nein-Nein ist. Hier ist die ganze Funktion:

%Vor%

Was ist der richtige Weg, die Funktion erneut aufzurufen?

Übrigens, ich benutze CodeIgniter, also $this .

    
Ronny-André Bendiksen 23.10.2009, 08:58
quelle

7 Antworten

25

Ich würde keine rekursiven Funktionen für Wiederholungsszenarien verwenden (da Sie das Ergebnis der Funktion nicht wiederverwenden, ist es sinnlos, Rekursion zu verwenden) ... Es fügt viel unnötigen Overhead hinzu. Tun Sie etwas wie folgt:

%Vor%

Wenn Sie in der Nähe der maximalen Anzahl von Tasten sind, führt dies zu sehr langen Loop-Zeiten, so dass Sie vielleicht eine Art von Maximalbegrenzung setzen möchten.

Oh, und wenn dies bei mehreren Threads gleichzeitig geschieht und Sie eine Datenbank überprüfen, sollten Sie die Schreibsperre für Tabellen implementieren, damit derselbe Schlüssel nicht zweimal eingefügt werden kann. Vorzugsweise sollte die Funktion, die prüft, ob ein Schlüssel verfügbar ist, sperren , prüfen und falls verfügbar schreiben in derselben Transaktion, um Kollisionen zu vermeiden.

    
Blixt 23.10.2009, 09:05
quelle
5

Sie müssen das Ergebnis des Selbstaufrufs zurückgeben, andernfalls wird der gültige Schlüssel nicht zurückgegeben, sobald er rekursiv ist.

%Vor%     
drewm 23.10.2009 09:06
quelle
2
  

aber dies bewirkt, dass die Funktion eine Endlosschleife ausführt,

Wenn Sie Ihre rekursive Strategie unbedingt beibehalten wollen, müssen Sie einen Endfall definieren. Zum Beispiel können Sie einen Zähler wie folgt definieren:

%Vor%

Es ist jedoch auch möglich, Ihren Code iterativ zu machen ...

    
Valentin Jacquemin 23.10.2009 09:04
quelle
2

Wenn Sie in Ihrer Schlüsselgenerierungsroutine genügend Eindeutigkeit angeben, können Sie diese Situation möglicherweise von vornherein vermeiden. Z.B. Lassen Sie die Routine den aktuellen Zeitstempel und den lokalen Hostnamen und / oder PID berücksichtigen.

Das Schleifen in einer solchen nicht-deterministischen Art ist im Allgemeinen der Beweis, dass ein Teil zu naiv ist. Das ist nicht gut. : -)

Wie auch immer, es wäre zumindest eine gute Übung, es zu erfassen und einen Fehler zu protokollieren, anstatt die Anfrage abzulegen und schließlich zu beenden:

%Vor%     
conny 23.10.2009 10:27
quelle
1

Warum scannen Sie nicht einfach den Schlüsselwertbereich für den ersten nicht verwendeten Schlüssel? Braucht der Schlüssel zusätzliche Einschränkungen zusätzlich zu vier Zeichen lang und einzigartig?

Sie können sich an die zuletzt zurückgegebene Taste erinnern, um bei nachfolgenden Anrufen mit dem Scannen fortzufahren.

Wenn Sie möchten, dass nachfolgende Anrufe keine ähnlichen Schlüssel zurückgeben, können Sie zuerst Ihre Schlüsseldatenbank mischen. Dies würde bedeuten, dass Sie irgendwo ein Elementarray 456976, 1679616, 7311616 oder 14776336 halten müssen (abhängig davon, ob das verwendete Alphabet ein- oder doppelschichtige Zeichen mit oder ohne Ziffern ist).

    
Svante 23.10.2009 10:56
quelle
1

Sie könnten Ihren Code in eine Schleife einfügen und stattdessen den Schlüssel iterativ bestimmen rekursiv .

Beispiel:

%Vor%

Die Schleife selbst verhindert keine unendliche Schleife, aber im Gegensatz zu einem Funktionsaufruf verbraucht dies keinen Stapelspeicherplatz, so dass Sie keinen Stapelüberlauf riskieren.

Auch es vereinfacht die Dinge ein wenig. Abhängig von der Art des Schlüssels können Sie auch die Schlüsselgenerierungsmethode anpassen, zum Beispiel mit nummerierten Schlüsseln, die Sie mit jeder Iteration exponentiell erhöhen können.

Anmerkungen: Wenn es möglich ist, verwenden Sie die Autoinkrementierungsfunktion einer Datenbank, anstatt Ihre eigene Schlüsselgenerierungsfunktion zu rollen.

Stellen Sie außerdem sicher, dass Sie Ihren Code vor gleichzeitigem Zugriff schützen. Was passiert, wenn zwei Instanzen dieser Funktion versuchen, einen Schlüssel zu generieren, und beide bestimmen das Gleiche? Verwenden Sie kritische Abschnitte oder Transaktionen, um sicherzustellen, dass nichts Schlimmes passiert.

    
Daniel Rikowski 23.10.2009 09:00
quelle
0

Verwenden einer Funktion in sich selbst

%Vor%     
karthik pyrate 14.04.2017 21:14
quelle