前言
今天在看一些c++代码时偶然间发现一些示例,在if语句的小括号内居然出现了分号,难道这一段是伪代码吗?之前从来没见过这种写法,然后写了一个例子,用最新的编译器编译后发现真的是正常的代码,并且可以成功运行,然后脑袋有个声音一闪而过,是不是一直就支持这种写法,只是我不知道而已,后来几经周折,终于发现真相,原来这其实是C++17新的语法。
if 语句本来的样子
C++17之前 if
语句的小括号内只能放判断逻辑,if (condition) { /* ... */ }
也就是这样,所以如果想使用一个变量进行判断,那么这个变量必须在if语句之前进行定义,比如我们常常使用的查找map元素的逻辑:
1 | { |
if 语句新能力
从C++17开始,if
语句的小括号之中也可以初始化变量了,语法为 if (initializer; condition) { /* ... */ }
,这样做的好处就是可以更加精细的控制变量的作用域,使代码看起来更加紧凑,比如上面的例子可以改写为:
1 | { |
最直观的感受就是少了一行代码,但是更重要的特点还是他把变量 it
的作用域限制在了 if
语句之内。
另外就是能一定程度上解决代码缩进层数太多的问题,这也是实际开发过程中遇到的问题,比如下面这段代码:
1 | { |
在C++17之前的代码中,因为 if
语句中不能包含初始化变量的逻辑,所以会造成 if
嵌套层层递进,当这种条件太多时,缩进层数太多导致代码可读性变差,使用C++17的语法再改进一下就变成了下面这样,逻辑更加清晰了:
1 | { |
switch
语句也是相同的能力扩展,就不再展开说了,这里贴一个 cppreference - switch 上的例子:
1 | { |
似曾相识在go中
这个在if中既初始化又进行判断的语法,之前在go中也用过,类似的需求在go中的写法是:
1 | func xxx() { |
是不是很像?其实在golang中更规范的用法是使用map查找的第二个返回值来判断元素是否存在,就像下面这样:
1 | func xxx() { |
关于语言的思考
看到上面这种golang和c++17的对比,会发现语言之间都在相互促进,这些所谓的高级语言,总能在其中一种语言中发现另一种语言的影子,也就是说在某些方面上他们是“趋同”的,可能在不久的将来会出现一种“超高级语言”,类似于C++模板机制,C++
、Golang
、Python
这些语言作为一种类型,传递到超高级语言之中,编写或者描述完功能逻辑后,自动生成对应语言的代码:
1 | SuperLanguageTemplate<C++/Golang/Python> |
总结
if
和switch
语句都可以在逻辑判断前初始化变量,变量的定义域可以更精细的控制- 编程语言之间相互“借鉴”,部分语法长得越来越像,最后不知道会不会归于统一
人生并不是不断失去,反过来看,其实人生应该是不断拥有,1秒,2秒,3秒,这些本就不一定属于你的时间,作为馈赠出现在了你的生命里~
2022-6-19 01:44:55