时间:2021-03-31 09:13:40 | 栏目:iOS代码 | 点击:次
语法糖
语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得?约翰?兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。
――维基百科
需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换;而且可以提高开发编码的效率。
通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会,本文在简单的介绍 OC 语法糖的同时也会跟大家分享下我们使用过程中发现的'新'问题。下面话不多说了,来一起看看详细的介绍吧。
语法糖的自白
先举个生活中的🌰:
老班巴拉巴拉讲了一堆,其实只是要表达*从明天起 7 点钟准时到校上课!*虽然最终能表达出效果,但是老班说的累小明们听着也烦。举这个例子可能比较极端,至少我没有遇到这么??嗦的老师。但在编程语言中的确有不少让程序员感到罗嗦的语法,让人不能忍,这个时候语法糖 就派上了用场。
比如OC取数组元素:
id element = [array1 objectAtIndex:0];
OC 语法糖:你看,我是不是写起来很方便?
id element = array1[0];
OC 语法糖:往下看,我还能做更多呢。
OC语法糖
@[] 和 @{}
NSArray
一般数组的初始化和访问数组元素是这样的:
// NSArray 的 alloc 初始化 NSArray *array1 = [[NSArray alloc] initWithObjects:@"a", @"b", @"c", nil]; // NSArray 的便捷构造 NSArray *array2 = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
获取数组中的元素可以这样的:
// 获取相应索引的元素 id element = [array1 objectAtIndex:0]; NSLog(@"array1_count = %d, array[0] = %@",[array1 count], element);
如果使用语法糖,可以这样写:
// NSArray的定义 NSArray *array = @[@"lu", @"da", @"shi", @YES, @123]; int count = (int)[array count]; for (int i = 0; i < count; i++) { NSLog(@"%@", array[i]); }
NSDictionary
字典的初始化一般是这样的:
NSDictionary *dictionay = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil]; id value = [dictionay objectForKey:@"key1"]; NSLog(@"key1 => %@", value);
我们还可以这样简化:
NSDictionary *dictionary = @{ @"key0" : @"value0", @"key1" : @"value1", @"key2" : @"value2" }; NSLog(@"key2 => %@", dictionary[@"key2"]);
事实上 [ ] 和 { } 在JSON数据格式中最常见了,[ ] 一般封装一个数组,{ } 一般封装一个整体对象。
NSNumber
一般写法是这样的:
NSNumber *intNumber = [NSNumber numberWithInt:123]; NSNumber *floatNumber = [NSNumber numberWithFloat:12.3]; NSNumber *charNumber = [NSNumber numberWithChar:@('a')];
语法糖简化写法:
NSNumber *a = @123; NSNumber *b = @12.3; NSNumber *c = @('a'); NSLog(@"a = %@, b = %@, c = %@", a, b, c);
. 点语法
再用数组 NSArray *array = @[@"lu", @"da", @"shi", @YES, @123]; 举例。想要获取数组中有多少个元素,我们平时都是怎么做的?
[array count] 还是 array.count?
老司机们思索片刻后说到:好像都用过,但是...我们知道在 OC 中 [] 和 . 分别代表调用方法和属性,看申明明明是属性呀,怎么可以用 . 方法?
从 OC 2.0 开始只要符合系统默认 setter、getter 书写格式的方法都可以使用. 点语法,属性是一对 getter、setter 方法,点语法是属性的另一种调用格式,就是语法糖方法。这么做的目的只有一个,就是增加可读性、兼容常见用法减少代码报错!
OC语法糖带来的'坑'
一般我们认为语法糖带来了方便,特别是对于字典的初始化 直接是key:value的赋值方式比 dictionaryWithObjectsAndKeys 这种反人类的方式友好的多。
但真的没有其他什么问题吗?看下下面两个定义及运行结果:
可见 dictionaryWithObjectsAndKeys 如果遇到 value 为 nil 的情况,后续 key-value 不会入库直接当做末尾 nil 结束初始化;
而语法糖的方式就直接崩溃了,对崩溃了。
所以使用语法糖还需要注意数据合法性问题,nil 会造成意外的崩溃哦!
基本原理
语法糖就是语言中的一个构件,当去掉该构件后并不影响语言的功能和表达能力。而使用语法糖语言的处理器,包括编译器,静态分析器等,会在处理之前把语法糖构件转换成加糖之前的构件,这个过程通常被称为:desugaring。说白了,语法糖就是对现有语法的一个封装,编译运行的时候再脱掉这层糖衣变为老的语法实现。
写在最后
之所以叫「语法」糖,不只是因为加糖后的代码功能与加糖前保持一致,更重要的是糖在不改变其所在位置的语法结构的前提下,实现了运行时等价。可以简单理解为,加糖后的代码编译后跟加糖前一摸一样。
之所以叫语法「糖」,是因为加糖后的代码写起来很爽,包括但不限于:代码更简洁流畅,代码更语义自然,写得爽,看着爽!
「糖」也可能有毒,使用需谨慎。
总结