最近刚开始学swift,遇到了一个非常诡异的问题。是在写for循环的时候出现语法错误。代码如下:
for var i = 0; i < 10; i++{ println("hello world") }
按理说这是Swift里最简单的for循环的使用了。但是编译器还是报了两个错:
- ‘++ is not a binary operator’
- Operator is not a known binary operator
虽然苹果在官方文档里面说,建议通过++i这种方式使用自增运算符,但是依然可以查到相关资料证明,++运算符既是一个前缀运算符(prefix operator),也是一个后缀运算符(postfix operator)。取决于它相对于变量的位置。虽然它作为前缀运算符和后缀运算符的作用不完全相同,但是写在for循环里面按理说是没有任何问题的。
仔细查了一下苹果介绍“Lexical Structure”的文档,(抱歉不会翻译,姑且称之为词法结构吧)。点击前往文档地址
其中有一段话介绍了运算符的前缀、后缀特性,摘录如下:
The whitespace around an operator is used to determine whether an operator is used as a prefix operator,a postfix operator,or a binary operator. This behavior is summarized in the following rules:
If an operator has whitespace around both sides or around neither side,it is treated as a binary operator. As an example,the + operator in a+b and a + b is treated as a binary operator.
If an operator has whitespace on the left side only,it is treated as a prefix unary operator. As an example,the ++ operator in a ++b is treated as a prefix unary operator.
If an operator has whitespace on the right side only,it is treated as a postfix unary operator. As an example,the ++ operator in a++ b is treated as a postfix unary operator.
第一段话告诉我们,一个运算符到底被swift编译器当做前缀运算符还是后缀运算符处理,是有一套规则的。依据的就是运算符左右的空格。
下面三段分别解释了如何定义前缀运算符,后缀运算符和二元运算符。
在文章的最开始的例子中,注意到我们的写法是i++{ 。那么++运算符左右皆无空格,因此被定义为二元运算符(binary operator)。但是在Swift对++运算符的定义中,它只能作为前缀运算符或者后缀运算符使用。于是错误就发生了。
那为什么会报第二个错误——Operator is not a known binary operator呢?
因为Swift中可以自定义运算符,在swift编译器尝试使用++运算符失败后,还会试图把++{作为一个自定义的运算符来理解,但是由于我们并没有实现过这个运算符,所以会报出未知运算符的错误。
for var i = 0; i < 10; ++i{ println("hello world") }
参考第二条规则,++运算符被正确识别为前缀运算符。由于官方文档推荐在使用自编运算符的时候使用前缀运算符,所以这种方式是被推荐的。
或者只要在{和++运算符之间添加空格即可。由于我习惯了i++的用法,所以更倾向于使用这种解决方案,代码如下:
for var i = 0; i < 10; i++ { println("hello world") }