objective-c 中圆括号的奇怪行为
Odd behaviour of round brackets in objective-c
我想知道为什么我的代码不能像我想的那样工作。请考虑以下代码:
- (NSString *)bake {
return [NSString stringWithFormat:(@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce])];
}
- (NSString *)cut {
return [NSString stringWithFormat:(@"Cut in 4 pieces")];
}
- (NSString *)box {
return [NSString stringWithFormat:(@"Box pizza. Ready for sale!")];
}
- (NSString *)orderString {
return [NSString stringWithFormat:@"%@ %@ %@", [self bake], [self cut], [self box]];
}
非常简单。现在,控制台输出结果为(即orderString
包含的内容):
Tobasko Cut in 4 pieces Box pizza. Ready for sale!
看起来由于某种原因,我们只从 bake NSString
中包含的文本中得到了最后一个词。编译器甚至用 2 "yellow" 警告警告这行代码:
Format string is not a string literal (potentially insecure)
Expression result unused
我只是通过删除圆括号来解决这个问题:
return [NSString stringWithFormat:@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce]];
但是,我不明白,为什么当我只是将语句放在圆括号中时编译器会截断我的字符串?
圆括号(不是圆括号)将其中的所有内容组合成一个表达式。更改某些运算符的优先级或使代码更具可读性很有用。
在基于 C 的语言中(包括 Objective-C),一系列逗号分隔的表达式的值是列表中最后一个表达式的值。
您行中的括号最终将 stringWithFormat:
方法的单独参数分组为单个参数,而不是预期的单独参数集。
因此值:
(@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce])
就是最后一个的值:
[self sauce]
所以实际上,你的台词真的只是:
return [NSString stringWithFormat:[self sauce]];
这就是为什么您会收到这两个警告以及为什么只有 returns Tobasko
.
此外,NSString stringWithFormat:
的使用应该总是至少有两个参数。第一个应该是一个至少有一个格式说明符的字符串,其余参数应该对应于格式字符串中的每个格式说明符。
所以代码如下:
return [NSString stringWithFormat:(@"Cut in 4 pieces")];
有两个问题。 1. 无意义的括号和 2. 没有必要使用 stringWithFormat:
。只需使用:
return @"Cut in 4 pieces";
我认为要了解正在发生的事情,我们需要将其分解为 3 个方面:
[NSString stringWithFormat:]
接受 1 个或多个参数。你可以只传入一个字符串,没有其他参数,它会 return 只是那个字符串。如果字符串中有格式描述符(例如 %@
、%d
等),则需要匹配数量的附加参数。但同样,没有格式描述符的单个字符串是有效参数。
括号()表示括号内的内容先求值,然后作为单个表达式使用
C 中的逗号运算符大致表示 "evaluate these expressions from left to right and return the value of the rightmost expression"
http://crasseux.com/books/ctutorial/The-comma-operator.html
那么在您的 "bake" 方法中发生的事情是:
- 首先将括号中的内容作为单个表达式求值
- 由于括号中的内容以逗号分隔,因此从左到右计算每个表达式,return 最右边表达式的值(在本例中为
[self sauce]
,计算结果为 @"Tabasko"
)
- 使用此单个表达式作为
[NSString stringWithFormat:]
的参数,即 [NSString stringWithFormat:@"Tabasko"];
在 "orderString" 之前的所有其他方法无论如何都只是单个字符串参数,因此括号不会对最终结果产生影响。
我想知道为什么我的代码不能像我想的那样工作。请考虑以下代码:
- (NSString *)bake {
return [NSString stringWithFormat:(@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce])];
}
- (NSString *)cut {
return [NSString stringWithFormat:(@"Cut in 4 pieces")];
}
- (NSString *)box {
return [NSString stringWithFormat:(@"Box pizza. Ready for sale!")];
}
- (NSString *)orderString {
return [NSString stringWithFormat:@"%@ %@ %@", [self bake], [self cut], [self box]];
}
非常简单。现在,控制台输出结果为(即orderString
包含的内容):
Tobasko Cut in 4 pieces Box pizza. Ready for sale!
看起来由于某种原因,我们只从 bake NSString
中包含的文本中得到了最后一个词。编译器甚至用 2 "yellow" 警告警告这行代码:
Format string is not a string literal (potentially insecure)
Expression result unused
我只是通过删除圆括号来解决这个问题:
return [NSString stringWithFormat:@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce]];
但是,我不明白,为什么当我只是将语句放在圆括号中时编译器会截断我的字符串?
圆括号(不是圆括号)将其中的所有内容组合成一个表达式。更改某些运算符的优先级或使代码更具可读性很有用。
在基于 C 的语言中(包括 Objective-C),一系列逗号分隔的表达式的值是列表中最后一个表达式的值。
您行中的括号最终将 stringWithFormat:
方法的单独参数分组为单个参数,而不是预期的单独参数集。
因此值:
(@"Take %@, put it in oven for 30 minutes, add 250 gramm of %@ cheese, many %@ toppings and little drop of %@ sauce", [self dough], [self cheese], [self toppings], [self sauce])
就是最后一个的值:
[self sauce]
所以实际上,你的台词真的只是:
return [NSString stringWithFormat:[self sauce]];
这就是为什么您会收到这两个警告以及为什么只有 returns Tobasko
.
此外,NSString stringWithFormat:
的使用应该总是至少有两个参数。第一个应该是一个至少有一个格式说明符的字符串,其余参数应该对应于格式字符串中的每个格式说明符。
所以代码如下:
return [NSString stringWithFormat:(@"Cut in 4 pieces")];
有两个问题。 1. 无意义的括号和 2. 没有必要使用 stringWithFormat:
。只需使用:
return @"Cut in 4 pieces";
我认为要了解正在发生的事情,我们需要将其分解为 3 个方面:
[NSString stringWithFormat:]
接受 1 个或多个参数。你可以只传入一个字符串,没有其他参数,它会 return 只是那个字符串。如果字符串中有格式描述符(例如%@
、%d
等),则需要匹配数量的附加参数。但同样,没有格式描述符的单个字符串是有效参数。括号()表示括号内的内容先求值,然后作为单个表达式使用
C 中的逗号运算符大致表示 "evaluate these expressions from left to right and return the value of the rightmost expression"
http://crasseux.com/books/ctutorial/The-comma-operator.html
那么在您的 "bake" 方法中发生的事情是:
- 首先将括号中的内容作为单个表达式求值
- 由于括号中的内容以逗号分隔,因此从左到右计算每个表达式,return 最右边表达式的值(在本例中为
[self sauce]
,计算结果为@"Tabasko"
) - 使用此单个表达式作为
[NSString stringWithFormat:]
的参数,即[NSString stringWithFormat:@"Tabasko"];
在 "orderString" 之前的所有其他方法无论如何都只是单个字符串参数,因此括号不会对最终结果产生影响。