Как написать лямбда-методы в Objective-C?
Как написать лямбда-методы в Objective-C?
Ответ 1
Концепция лямбда в Objective-C теперь инкапсулирована идеей Blocks, которая являются эквивалентом функций сквозной ссылки. Конечно, возможно, у кого-то было уже с C с идеей указателей функций; блоки - это просто способ захвата локального состояния (т.е. может быть замыканием). Фактически, блоки также могут использоваться и на других языках C (на Mac) - есть предложение сделать их частью стандартного синтаксиса C.
Здесь пример определения lambda для умножения двух чисел:
int (^mult)(int, int) = ^(int a, int b) { return a*b; };
Первая часть объявляет переменную типа ^int(int,int)
, а затем присваивает ее выражению лямбда (aka block), которое возвращает кратное его двух аргументов. Затем вы можете передать это fn вокруг, определить его в других местах и т.д.; вы можете даже использовать его в других функциях.
Здесь пример определения функции, которая при вызове возвращает другую функцию:
multiplyBy = ^(int a) { return ^(int b) { return b*a; }; };
triple = multiplyBy(3);
Обратите внимание, что вы можете смешивать блоки с типами объектов (обычно используя id
в качестве типа объекта), и многие из новых структур данных объекта Objective-C имеют некоторую операцию на блочном уровне. GCD также использует блоки для прохождения в произвольных событиях; однако обратите внимание, что GCD также можно использовать с указателями функций.
Ответ 2
OS X 10.6 введены блоки. См. ответ AlBlue для примеров.
Если вы не используете Snow Leopard, вы можете получить что-то близкое к композиции функций, используя различные другие функции.
Пример использования указателей функций C:
void sayHello() {
NSLog(@"Hello!");
}
void doSomethingTwice(void (*something)(void)) {
something();
something();
}
int main(void) {
doSomethingTwice(sayHello);
return 0;
}
Пример использования шаблона команды:
@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;
}
Пример использования селектора:
@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;
}
Ответ 3
Я слышал, как Андре Панг в NSConference рассказывал о том, как будут собираться блоки со следующей версией Objective-C.
Это должно позволить функциональное программирование.
Изменить: поскольку Snow Leopard выпущен, это действительно так. Objective-C теперь имеет Blocks.