Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
fun with Obj-C "generics"
@import Foundation;
NS_ASSUME_NONNULL_BEGIN
@interface Function<__contravariant InType, __covariant OutType> : NSObject
{
// interestingly, this does work here (though OutType & InType are not available in the @implementation)
OutType (^_block)(InType);
}
- (instancetype)initWithBlock:(OutType (^)(InType))block;
- (OutType)evaluateAt:(InType)value;
@end
NS_ASSUME_NONNULL_END
// Unfortunately, the generated Swift interface is not very useful:
import Foundation
class Function : NSObject {
init(block: (AnyObject) -> AnyObject)
func evaluateAt(value: AnyObject) -> AnyObject
}
@import Foundation;
#import "Function.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Function<NSString *, NSArray<NSString *> *> *stringSplitter = [[Function alloc] initWithBlock:^(NSString *str) {
return [str componentsSeparatedByString:@","];
}];
// works (unspecified)
NSArray *__unused result0 = [stringSplitter evaluateAt:@"hello,there"];
// works (all NSStrings are NSObjects)
NSArray<NSObject *> *__unused result1 = [stringSplitter evaluateAt:@"hello,there"];
// warning: incompatible pointer types ... (not all NSStrings are NSMutableStrings)
NSArray<NSMutableString *> *__unused result2 = [stringSplitter evaluateAt:@"hello,there"];
// works (all NSMutableStrings are NSStrings)
Function<NSMutableString *, NSArray<NSObject *> *> *__unused mutableStringSplitter = stringSplitter;
// warning: incompatible pointer types ... (not all NSObjects are NSStrings)
Function<NSObject *, NSArray<NSString *> *> *__unused arbitrarySplitter = stringSplitter;
// warning: incompatible pointer types ... (not all NSStrings are NSMutableStrings)
Function<NSString *, NSArray<NSMutableString *> *> *__unused stringSplitterToMutable = stringSplitter;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment