在現實生活中有集合的概念,我們的思考習慣會將一系列一模一樣的事情放在集合裡面,例如同學們。在程式語言是一樣的道理,我們也偏好。
在 Swift 我們可以使用 <...>
定義泛型
// Swift
class Stack<T:Equatable> {
func push(_:T)
func pop() -> T
}
在 Objective-C 2.0 之後,提供了泛型指定的功能,所使用的修飾語法為 __covariant
與 __contravariance
(協變與逆變 [註 1])。
// Objective-C
/* Stack.h */
@interface Stack <__covariant ObjectType> : NSObject
- (void)push:(ObjectType)value;
- (ObjectType) pop;
@end
在 header 檔內,ObjectType
是可以取得的,但是在 .m
檔中是無法取得的。
// Objective-C
/* Stack.m */
#pragma private property
@interface Stack ()
@property NSMutableArray* list;
@end
@implementation Stack
- (instancetype) init {
if (self = [super init])
self.list = [[NSMutableArray alloc] init];
return self;
}
- (void)push:(id)value {
[_list addObject: value];
return;
}
- (id)pop {
id object = [_list lastObject];
[_list removeLastObject];
return object;
}
@end
最後,我們透過宣告了泛型的型別,一旦後續使用的型別是不一樣的,會有錯誤警告。
// Objective-C
/* main.m */
Stack<NSNumber*>* stack = [[Stack alloc] init];
[stack push: @1];
NSString* s = [stack pop]; // Warning: 1
Incompatible pointer types initializing 'NSString *' with an expression of type 'NSNumber *'