Πώς να πυροδοτήσει μια λειτουργία μία φορά και μόνο μία φορά ...;

ψήφοι
6

Μου συμβαίνει συχνά να προκαλέσει μια συγκεκριμένη λειτουργία μόνο μία φορά, αλλά θα πρέπει να το ενεργοποιήσουν μέσα από μια άλλη λειτουργία που παίρνει επανειλημμένα. Για παράδειγμα, λαμβάνοντας ένα στιγμιότυπο κάτι για μελλοντική χρήση. Συνήθως το κάνω με τον καθορισμό ενός παγκόσμιου boolean.

Αναρωτιέμαι αν ο τρόπος που το κάνω είναι πραγματικά καλύτερος τρόπος;

Θυμάμαι την ανάγνωση ότι οι παγκόσμιες μεταβλητές είναι κακό, και η παγκόσμια boolean μεταβλητές είναι ακόμα χειρότερα!

Τέλος πάντων, αυτό είναι το πώς συνήθως ολοκληρώσει προκαλώντας μια συγκεκριμένη μέθοδο μόνο μία φορά:

Στην αρχική μου σύνολο των μεταβλητών ...

private var myStatus:Boolean = false;

Στη συνέχεια, στο πλαίσιο της λειτουργίας που παίρνει ονομάζεται συχνά ...

if (!myStatus) {
    doMyFunction();
    myStatus = true;
}

Φαίνεται αρκετά λογικό για μένα, αλλά είναι το σωστό ;

UPDATE : Λοιπόν, με βάση ό, τι έμαθα από τις απαντήσεις σας, αντί για τον έλεγχο μιας παγκόσμιας boolean μεταβλητή, τώρα ελέγξτε πρώτα αν υπάρχει ο κόμβος XML (είμαι αποθήκευση των εικόνων μέσα σε μια δομή XML πριν από κάθε γραπτώς να συμβεί δίσκο), και, αν δεν το κάνει, τότε θα προσθέσετε ένα νέο κόμβο με τις κωδικοποίηση base64 δεδομένα εικόνας. Κάνω ακόμα οριστεί μια δυαδική σημαία, έτσι ώστε αργότερα μπορώ να αντικαταστήσετε το κενό εικόνα με δεδομένα εικόνας χρήστη επεξεργασία, αν χρειαστεί. Λειτουργεί άψογα. Σας ευχαριστώ όλους για τη βοήθειά σας!

Επίσης, τώρα αισθάνονται πιο άνετα σχετικά με τη χρήση αυτού του συγκεκριμένου συστήματος (μη ασφαλές το νήμα) σε ορισμένες περιπτώσεις.

Δημοσιεύθηκε 09/12/2008 στις 23:59
πηγή χρήστη
Σε άλλες γλώσσες...                            


7 απαντήσεις

ψήφοι
7

Όταν καλείτε μια λειτουργία που πρέπει να κάνει ό, τι περιμένετε να κάνει με τα επιχειρήματα που δίνετε. Αν καλέσετε μια συνάρτηση δύο φορές με τον ίδιο ακριβώς τρόπο θα πρέπει να αναμένουμε ότι η λειτουργία για να σας δώσει τα ίδια αποτελέσματα ή να κάνετε το ίδιο πράγμα.

Είναι ίσως καλύτερα να προχωρήσουμε σε αυτή την κλήση, για άλλη μια εξάρτηση με τη λογική που απαιτεί η λειτουργία πολλές φορές σας. Αν το μόνο που χρειάζεται να καλέσετε τη λειτουργία μία φορά, τότε καλέστε μόνο μία φορά. Εναλλακτικά, περνούν διάφορα επιχειρήματα για τη λειτουργία για να δείξει ότι κάνετε κάτι διαφορετικό.

Απαντήθηκε 10/12/2008 στις 00:17
πηγή χρήστη

ψήφοι
5

Είναι πραγματικά εξαρτάται από ακριβώς τι εννοείς. Αν θα γίνει επίκληση κωδικό σας από περισσότερες από μία κλωστή, τότε έχετε μια κατάσταση κούρσας που θα μπορούσε να σημαίνει ότι doMyFunctionθα μπορούσε να ονομάζεται πολλές φορές. Αυτό οφείλεται στο γεγονός ότι περισσότερα από ένα νήμα θα μπορούσε να ελέγξει myStatus, να δείτε ότι είναι ψευδής, τότε επικαλούνται doMyFunction. Μπορείτε να βελτιώσετε την κατάσταση λίγο θέτοντας τη μεταβλητή πρώτο:

if (!myStatus) {
    myStatus = true;
    doMyFunction();
}

αλλά αυτό περιορίζει μόνο το παράθυρο για τα προβλήματα, δεν θα εξαλειφθεί.

Για να εξαλειφθεί η κατάσταση κούρσας, θα πρέπει να έχετε μια κλειδαριά.

Απαντήθηκε 10/12/2008 στις 00:06
πηγή χρήστη

ψήφοι
4

Στην C / C ++ μπορείτε να κρατήσετε συνήθως το γεγονός ότι doMyFunction () καλείται μόνο μία φορά έγκλειστα χρησιμοποιώντας μια στατική μεταβλητή, όπως αυτό:

void doMyFunction() {
     // gets called only once.
     // side effects go here.
}

void functionThatGetsCalledALot() {
    static bool called = false;
    if (!called) {
        doMyFunction();
        called = true;
    }
    // do more stuff
}

Έτσι, αποφεύγεται η χρήση των διεθνοποιημένων, αλλά έχει το ίδιο αποτέλεσμα, και η στατική var έχει δηλωθεί σωστά όπου είναι σχετικό, ώστε να είναι σαφές τι συμβαίνει. Σημειώστε ότι αυτό δεν είναι το νήμα-ασφαλή, οπότε θα χρειαστεί μια κλειδαριά, αν έχετε θέματα.

Απαντήθηκε 10/12/2008 στις 00:09
πηγή χρήστη

ψήφοι
2

Δεν είναι το νήμα-ασφαλή. Αυτό δεν μπορεί να έχει σημασία για σας, αλλά εσείς είπατε «γλώσσα-αγνωστικιστής»: μάλλον δεν θα θέλετε να χρησιμοποιήσετε αυτό το μοτίβο σε μια βιβλιοθήκη γενικής χρήσης για Java.

Αυτή είναι μια δύσκολη ερώτηση για να απαντήσει σε μια γλώσσα-αγνωστικιστής τρόπο, επειδή οι διαθέσιμες εναλλακτικές λύσεις πολύ εξαρτώνται από τη γλώσσα. Για παράδειγμα, στο POSIX έχετε pthread_once αν χρειάζεται το νήμα-ασφάλειας. Στην C έχετε στατική τοπικές μεταβλητές για να πάρει ότι boolean από την παγκόσμια εμβέλεια. Σε κάθε OO γλώσσα, αν παίρνετε ένα στιγμιότυπο του «κάτι» για μελλοντική χρήση, τότε θα μπορούσε να υπάρχει ένα κατάλληλο αντικείμενο που αντιστοιχεί στο «κάτι» (ή με το στιγμιότυπο), το οποίο θα μπορούσε να αποθηκεύσει τη σημαία.

Απαντήθηκε 10/12/2008 στις 00:09
πηγή χρήστη

ψήφοι
0

Στην Perl 5.10 ή νεότερη έκδοση, θα πρέπει να χρησιμοποιήσετε μια stateμεταβλητή.

use 5.010;

sub test{
  state $once = 1;

  if( $once ){
    $once = undef;
    say 'first';
  } else {
    say 'not first';
  }
}

test for 1..5;

εξόδους

πρώτα
δεν είναι η πρώτη
δεν είναι η πρώτη
δεν είναι η πρώτη
δεν είναι η πρώτη
Απαντήθηκε 10/12/2008 στις 21:01
πηγή χρήστη

ψήφοι
0

Δεν βλέπω άλλο τρόπο. Το μόνο πράγμα που έρχεται στο μυαλό για το πώς να βελτιώσουν αυτό είναι - η ασφάλεια νήμα. Αλλά αυτό είναι απαραίτητο μόνο αν έχετε πολλαπλά threads κλήση της συνάρτησης.

Απαντήθηκε 10/12/2008 στις 00:06
πηγή χρήστη

ψήφοι
0

Δεν βλέπω τίποτα λάθος με την προσέγγισή σας εδώ. Λάβετε υπόψη σας, δεν υπάρχει πάντα το «δεξί» το πράγμα ... Δεν υπάρχουν definetly λάθος πράγματα, αλλά αυτό που είναι σωστό μπορεί να είναι υποκειμενική, και μπορεί επίσης να εξαρτάται βάση δραματικά τις απαιτήσεις του συστήματος.

Απαντήθηκε 10/12/2008 στις 00:02
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more