我们应该写 `[NSMutableArray<NSString *> array]` 吗?
Should we write `[NSMutableArray<NSString *> array]`?
Xcode 7 引入了泛型。它允许提示,例如:
并允许警告,例如:
但是很多事情都失败了,根本没有任何警告:
NSMutableArray<NSNumber *> *array;
array = [NSMutableArray<NSNumber *> arrayWithObjects:@0, @"", nil];
NSLog(@"%@", [array[1] class]);// __NSCFConstantString
array = [NSMutableArray<NSNumber *> arrayWithContentsOfURL:[NSURL URLWithString:@"http://ios.eezytutorials.com/sample-files/sample-array-plist.plist"]];
NSLog(@"%@", [array[0] class]); // __NSCFString
所以键入通用创建有点不可靠。
问题:我们应该使用不可靠的语法吗?
NSMutableArray<NSString *> *array;
array = [NSMutableArray<NSString *> array];
array = [NSMutableArray<NSString *> arrayWithArray:array];
array = [NSMutableArray<NSString *> arrayWithObjects:@"", @"", nil];
array = [NSMutableArray<NSString *> arrayWithContentsOfURL:url];
或者简化语法?
NSMutableArray<NSString *> *array;
array = [NSMutableArray array];
array = [NSMutableArray arrayWithArray:array];
array = [NSMutableArray arrayWithObjects:@"", @"", nil];
array = [NSMutableArray arrayWithContentsOfURL:url];
我还担心,显然不可能为 arrayWithContentsOfURL
和 arrayWithContentsOfFile
的 return 值提供任何编译时保证。那么泛型对那些人总是没用吗?
是的,应该使用泛型来为编译器和开发人员提供更多的类型规范信息。
提供数组将包含在声明中的对象类型至少是一种文档增益,错误检查是一个额外的好处。
也希望在未来版本的编译器中改进类型检查。
但一般来说,意外地在数组中混合类型并不是问题,此类错误往往表明开发人员的困惑。如果我有一个 Motorcycle
对象数组并添加一个 Juggler
对象,我要么有主要的设计不匹配错误,要么有严重的混淆。
最好的防御是class和变量命名,不是array
而是motorcycleList
和jugglerList
。然后,如果我有 motorcycleList addObject:juggler
,很快就会发现在编写语句时出现错误。
添加到 ObjC 语言只是显式规范进程中的一个步骤:
id x = [NSMutableArray new];
NSMutableArray *list = [NSMutableArray new];
NSArray<NSString *> *stringList = [NSMutableArray new];
你说得对,Obj-C 中的泛型并不完美,但是:
- 某些类型检查比 none
更好
- 使代码更加self-documenting
- Xcode 的未来版本可以改进类型推断
- 它已经使与 Swift 的集成变得顺畅了——随着时间的推移它只会变得越来越重要
缺点:
- 没有发现 100% 的错误 -- 但有任何发现吗?
- 给您的代码增加一些额外的麻烦
总而言之:现在略有改进,但会使您的代码更加 future-proof。
因为它确实会触发问题中描述的警告,所以使用具有指定泛型类型 ([NSMutableArray<NSString *> ...];
) 的构造函数是更好的方法。
但我们可以假设 Objective-C 中引入泛型是为了过渡到 Swift,在这方面,直接使用 Swift 更好.
Xcode 7 引入了泛型。它允许提示,例如:
并允许警告,例如:
但是很多事情都失败了,根本没有任何警告:
NSMutableArray<NSNumber *> *array;
array = [NSMutableArray<NSNumber *> arrayWithObjects:@0, @"", nil];
NSLog(@"%@", [array[1] class]);// __NSCFConstantString
array = [NSMutableArray<NSNumber *> arrayWithContentsOfURL:[NSURL URLWithString:@"http://ios.eezytutorials.com/sample-files/sample-array-plist.plist"]];
NSLog(@"%@", [array[0] class]); // __NSCFString
所以键入通用创建有点不可靠。
问题:我们应该使用不可靠的语法吗?
NSMutableArray<NSString *> *array;
array = [NSMutableArray<NSString *> array];
array = [NSMutableArray<NSString *> arrayWithArray:array];
array = [NSMutableArray<NSString *> arrayWithObjects:@"", @"", nil];
array = [NSMutableArray<NSString *> arrayWithContentsOfURL:url];
或者简化语法?
NSMutableArray<NSString *> *array;
array = [NSMutableArray array];
array = [NSMutableArray arrayWithArray:array];
array = [NSMutableArray arrayWithObjects:@"", @"", nil];
array = [NSMutableArray arrayWithContentsOfURL:url];
我还担心,显然不可能为 arrayWithContentsOfURL
和 arrayWithContentsOfFile
的 return 值提供任何编译时保证。那么泛型对那些人总是没用吗?
是的,应该使用泛型来为编译器和开发人员提供更多的类型规范信息。
提供数组将包含在声明中的对象类型至少是一种文档增益,错误检查是一个额外的好处。
也希望在未来版本的编译器中改进类型检查。
但一般来说,意外地在数组中混合类型并不是问题,此类错误往往表明开发人员的困惑。如果我有一个 Motorcycle
对象数组并添加一个 Juggler
对象,我要么有主要的设计不匹配错误,要么有严重的混淆。
最好的防御是class和变量命名,不是array
而是motorcycleList
和jugglerList
。然后,如果我有 motorcycleList addObject:juggler
,很快就会发现在编写语句时出现错误。
添加到 ObjC 语言只是显式规范进程中的一个步骤:
id x = [NSMutableArray new];
NSMutableArray *list = [NSMutableArray new];
NSArray<NSString *> *stringList = [NSMutableArray new];
你说得对,Obj-C 中的泛型并不完美,但是:
- 某些类型检查比 none 更好
- 使代码更加self-documenting
- Xcode 的未来版本可以改进类型推断
- 它已经使与 Swift 的集成变得顺畅了——随着时间的推移它只会变得越来越重要
缺点:
- 没有发现 100% 的错误 -- 但有任何发现吗?
- 给您的代码增加一些额外的麻烦
总而言之:现在略有改进,但会使您的代码更加 future-proof。
因为它确实会触发问题中描述的警告,所以使用具有指定泛型类型 ([NSMutableArray<NSString *> ...];
) 的构造函数是更好的方法。
但我们可以假设 Objective-C 中引入泛型是为了过渡到 Swift,在这方面,直接使用 Swift 更好.