Ruby || = Objective-C中的等价物

我一直在学习ruby,我基本上爱上了|| = feature,因为它会让Objective L中的懒惰getter更容易。

目前我写的吸气剂如:

- (NSArray *)myArray { if (!_myArray) { _myArray = [NSArray array]; } return _myArray } 

除非我遗漏了|| =的东西,否则我可以使用以下代码在Ruby中编写前面的代码:

 - (NSArray *)myArray { return _myArray ||= [NSArray array]; } 

多数民众赞成显然更清洁。 Objective-C语言/运行时中是否有任何可以使您执行此操作的内容?

此外,以下是吸气剂的单行三元组,我不确定它是否与上面发布的尝试和真实方法一样有效(第一个片段)。 如果有人做错了,有人可以告诉我:

 - (NSArray *)myArray { return _myArray = _myArray ? _myArray : [NSArray array]; } 

最后一个片段与您发布的第一个片段具有相同的效果。

作为改进,虽然在Objective-C中没有类似||=的运算符,但你可以省略三元运算符的第二个参数if

 return _myArray = _myArray ?: [NSArray array]; 

这完全等同于

 return _myArray = _myArray ? _myArray : [NSArray array]; 

这是gcc和clang的现代版本支持的语言扩展。

奖励:如果你想节省更多的击键,你可以做到

 - (NSArray *)myArray { return _myArray = _myArray ?: @[]; } 

作为旁注,跳过中间操作数也可以带来一些好处。

例如在这种情况下

 id x = [self someMethod] ? [self someMethod] : [self anotherMethod]; 

如果someMethod计算结果为true ,它将被调用两次,而这样做

 id x = [self someMethod] ?: [self anotherMethod]; 

它只会被调用一次。

除非你想攻击Clang ,否则没有字面上的等价物。 || 逻辑运算符虽然短路,但不会评估其操作数。 使用三元条件的宏将使您接近:

 #define NON_NIL(o, p) ((o) ? (o) : (p)) - (NSMutableArray *)myArray { return _myArray = NON_NIL(_myArray, [NSMutableArray array]); } 

因为C类中的赋值行为类似于表达式并且计算为指定的值。

你实际上也可以创建一个OR_ASSIGN()宏,但是我将把它留给完全疯狂读者的练习。

也许同样疯狂的是一个function:

 id lazySet(id *obj; id(^valBlock)(void)) { if( !(*obj) ){ *obj = valBlock(); } return *obj; } - (NSMutableArray *)myArray { return lazySet(&_myArray, ^{return [NSMutableArray array]}); } 

但那太荒谬了。