Question Comment écrire les méthodes lambda dans Objective-C?


Comment écrire les méthodes lambda dans Objective-C?


61
2018-06-03 10:16


origine


Réponses:


Le concept de lambda dans Objective-C est maintenant encapsulé avec l'idée de Blocs qui sont l'équivalent des fonctions de référence par référence. Bien sûr, on peut déjà penser à C avec l'idée de pointeurs de fonctions. les blocs ne sont qu'un moyen de capturer également l'état local (c.-à-d. peuvent être des fermetures). En fait, les blocs peuvent également être utilisés dans d'autres langages C (sur Mac) - il existe une proposition pour les intégrer à la syntaxe C standard.

Voici un exemple de définition d'un lambda pour multiplier deux nombres:

int (^mult)(int, int) = ^(int a, int b) { return a*b; };

La première partie déclare une variable, de type ^int(int,int) puis l'attribue à l'expression lambda (aka bloc) qui renvoie le multiple de ses deux arguments. Vous pouvez alors transmettre cette information, la définir ailleurs, etc. vous pouvez même l'utiliser dans d'autres fonctions.

Voici un exemple de définition d'une fonction qui, lorsqu'elle est appelée, renvoie une autre fonction:

multiplyBy = ^(int a) { return ^(int b) { return b*a; }; };
triple = multiplyBy(3);

Notez que vous pouvez mélanger des blocs avec des types d'objet (en utilisant généralement id en tant que type d'objet) et de nombreuses nouvelles structures de données d'objet Objective-C ont une sorte d'opération au niveau du bloc. GCD utilise également des blocs pour transmettre des événements arbitraires; Cependant, notez que GCD peut également être utilisé avec des pointeurs de fonction.


87
2017-11-27 20:03



OS X 10.6 a introduit des blocs. Voir La réponse d'AlBlue pour des exemples.

Si vous n'utilisez pas Snow Leopard, vous pouvez obtenir quelque chose proche de la composition des fonctions en utilisant diverses autres fonctionnalités.

Exemple utilisant des pointeurs de fonction C:

void sayHello() {
    NSLog(@"Hello!");
}

void doSomethingTwice(void (*something)(void)) {
    something();
    something();
}

int main(void) {
    doSomethingTwice(sayHello);
    return 0;
}

Exemple utilisant le modèle de commande:

@protocol Command <NSObject>
- (void) doSomething;
@end

@interface SayHello : NSObject <Command> {
}
@end

@implementation SayHello
- (void) doSomething {
    NSLog(@"Hello!");    
}
@end

void doSomethingTwice(id<Command> command) {
    [command doSomething];
    [command doSomething];
}

int main(void) {
    SayHello* sayHello = [[SayHello alloc] init];
    doSomethingTwice(sayHello);
    [sayHello release];
    return 0;
}

Exemple utilisant un sélecteur:

@interface SaySomething : NSObject {
}
- (void) sayHello;
@end

@implementation SaySomething
- (void) sayHello {
    NSLog(@"Hello!");    
}
@end

void doSomethingTwice(id<NSObject> obj, SEL selector) {
    [obj performSelector:selector];
    [obj performSelector:selector];
}

int main(void) {
    SaySomething* saySomething = [[SaySomething alloc] init];
    doSomethingTwice(saySomething, @selector(sayHello));
    [saySomething release];
    return 0;
}

27
2018-06-03 11:42



J'ai entendu André Pang à NSConference parler de la manière dont les blocs allaient être introduits avec la prochaine version d'Objective-C.

Cela devrait permettre une programmation fonctionnelle.

Edit: Depuis la sortie de Snow Leopard, c'est effectivement le cas. Objective-C a maintenant Blocs.


3
2018-06-03 11:49