【问题标题】:Odd behaviour of round brackets in objective-cObjective-c中圆括号的奇怪行为
【发布时间】:2015-10-21 23:12:58
【问题描述】:

我想知道为什么我的代码不能像我想的那样工作。请考虑以下代码:

- (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 个“黄色”警告警告这行代码:

格式字符串不是字符串文字(可能不安全)

表达式结果未使用

我只是通过删除这样的圆括号来解决这个问题:

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]];

但是,我不明白,当我简单地将语句放在圆括号中时,为什么编译器会截断我的字符串?

【问题讨论】:

  • 它们被称为括号。

标签: objective-c nsstring


【解决方案1】:

括号(不是圆括号)将其中的所有内容组合成一个表达式。更改某些运算符的优先级或使代码更具可读性很有用。

在基于 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]];

这就是为什么您会收到两个警告以及为什么它只返回 Tobasko

此外,NSString stringWithFormat: 的使用应始终至少有两个参数。第一个应该是一个至少有一个格式说明符的字符串,其余参数应该对应格式字符串中的每个格式说明符。

所以代码如下:

return [NSString stringWithFormat:(@"Cut in 4 pieces")];

有两个问题。 1. 无意义的括号和 2. 没有必要使用stringWithFormat:。只需使用:

return @"Cut in 4 pieces";

【讨论】:

    【解决方案2】:

    我认为要了解正在发生的事情,我们需要将其分解为 3 个方面:

    1. [NSString stringWithFormat:] 接受 1 个或多个参数。你可以只传入一个字符串,没有其他参数,它只会返回那个字符串。如果字符串中有格式描述符(例如%@%d 等),则需要匹配数量的附加参数。但同样,没有格式描述符的单个字符串是有效参数。

    2. 括号 () 表示应先计算括号内的内容,然后将其用作单个表达式

    3. C 中的逗号运算符大致意思是“从左到右计算这些表达式并返回最右边表达式的值”

    http://crasseux.com/books/ctutorial/The-comma-operator.html

    所以在你的“烘焙”方法中发生的事情是:

    1. 首先将括号的内容作为单个表达式求值
    2. 由于括号的内容是用逗号分隔的,因此从左到右计算每个表达式,并返回最右边的表达式的值(在本例中为 [self sauce],其计算结果为 @"Tabasko"
    3. 将此单个表达式用作[NSString stringWithFormat:] 的参数,即[NSString stringWithFormat:@"Tabasko"];

    “orderString”之前的所有其他方法都只是单个字符串参数,因此括号对最终结果没有影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多