天天看點

為什麼Swift和Python要抛棄++\--?

為什麼Swift和Python要抛棄++--?

簡單好用的++、--

說到自增(++)自減(--)運算符,小夥伴們應該都不會陌生,在很多程式設計語言的代碼中,都經常出現它們的身影。

比如常用的for語句

複制代碼

C CPP

for (int i = 0; i < n; i++) {

// TODO

}

比如經典的一行代碼實作字元串拷貝

// 将src的内容拷貝至dest

void strcpy(char dest, char src) {

while (dest++ = src++);

int main() {

char s1[10], *s2 = "xmg_mj";

strcpy(s1, s2);

printf("%s", s1); // xmg_mj

return 0;

使用得當的話,自增(++)自減(--)運算符的确可以讓代碼簡潔又優雅。

但是

2大熱門程式設計語言Swift、Python并不支援自增(++)、自減(--)運算符,這是為什麼呢?

這裡先給出幾個參考連結,有興趣的小夥伴可以自行去閱讀一下:

Swift之父Chris Lattner的說明

從Swift3開始不支援++、--

https://github.com/apple/swift-evolution/blob/master/proposals/0004-remove-pre-post-inc-decrement.md

來自Stack Overflow的一個問答

Why are there no ++ and -- operators in Python?

https://stackoverflow.com/questions/3654830

來自Google研發總監(Director of Research)Peter Norvig的觀點

The Python IAQ: Infrequently Answered Questions

http://norvig.com/python-iaq.html

這裡隻列出幾個顯而易見的理由

有了強大又簡潔的for-in,for語句中可以完全不需要++、--

Swift

// C++

for (int i = 0; i < 5; i++) {

cout << i << endl;

// Swift

for i in 0..<5 {

println(i)

// Python

for i in range(5):

print(i)

盡管while (d++ = s++);看起來似乎簡單而優雅,但對于初學者來說絕非簡單,會增加學習成本。而Swift、Python更傾向于希望任何人都能快速上手這門程式設計語言。

當混合使用字首和字尾的++、--時

會降低代碼的可讀性,比如while (n++ > --k),經驗豐富的程式員也必須停下來思考一下代碼的具體含義是什麼

運作結果可能會有不确定性

運作結果的不确定性

下面列出2段代碼,變量b的結果是什麼呢?(值得一提的是:實際開發中我們并不會這麼寫,這裡把它列出來僅僅是為了讨論一些技術細節)

int a, b;

// 第1段代碼

a = 1;

b = a++ + ++a + a++ + ++a;

// 第2段代碼

b = a++ + a++ + a++ + a++;

實際上,上面的C語言代碼在MSVC、MinGW編譯器下得出的結果是不完全一緻的

MSVC:微軟出品

MinGW:GNU出品(可以了解為Windows版本的GCC)

第1段代碼

結果一緻,符合絕大部分人的預期,是以就不展開讨論了

// MSVC:b = 1 + 3 + 3 + 5 = 12

// MinGW:b = 1 + 3 + 3 + 5 = 12

第2段代碼

結果不一緻

MSVC的結果是1 + 1 + 1 + 1 = 4

MinGW的結果是1 + 2 + 3 + 4 = 10

// MSVC:b = 1 + 1 + 1 + 1 = 4

// MinGW:b = 1 + 2 + 3 + 4 = 10

你可能好奇:你怎麼知道MinGW的計算過程是1 + 2 + 3 + 4呢?根據最終結果10反推回去猜出來的麼?NO!如果是這樣做的話,那就有點侮辱了程式員這個職業了。

像這種不太容易從表面去了解的代碼,你若想知道它的真正本質,那就要搬出強有力且精準的武器了,它就是彙編語言(Assembly Language)。

簡單說明一下使用彙編語言的理由:

衆所周知,C語言代碼最終都會被編譯為機器語言代碼(也叫做機器指令,隻由0和1組成)

那通過研究最終的機器指令來探索C語言代碼的本質?由于機器指令極其晦澀難懂,是以,對一般人來說,這并不是一種高效的辦法

最佳的辦法是:研究一下介于C語言、機器語言之間的彙編語言代碼

C語言 → 彙編語言 ↔ 機器語言

彙編語言代碼比機器指令可讀性高很多

每一條機器指令都有與之對應的彙編語言代碼

是以,你研究彙編語言代碼,基本就等同于研究機器指令,可讀性+精準性兼具

看看MSVC環境下的彙編代碼

紅框代碼:将4個a相加的結果指派給b,由于a的初始值是1,是以b = 1 + 1 + 1 + 1 = 4

綠框代碼:讓a執行4次自增1的操作,相當于執行4次a += 1

看看MinGW環境下的彙編代碼

為了保證能基本看懂這段彙編代碼,建議你可以了解為[rbp-0x4]代表變量a,[rbp-0x8]代表變量b

綠框代碼:讓a執行自增1的操作,相當于執行a += 1

紅框代碼:将a每次自增1之前的值累加起來,最後指派給b

可以看到,綠框、紅框代碼是交替執行的,是以最終b = 1 + 2 + 3 + 4 = 10

最後2段代碼

最後再放2段代碼出來,在MSVC和MinGW下的結果也是不一緻的

b = ++a + ++a + ++a + ++a;

// MSVC:b = 5 + 5 + 5 + 5 = 20

// MinGW: b = 3 + 3 + 4 + 5 = 15

b = ++a + ++a + a++ + a++;

// MSVC:b = 2 + 3 + 3 + 4 = 12

// MinGW:b = 3 + 3 + 3 + 4 = 13

根據前面的一些講解,相信你現在可以推斷出MSVC的結果了。

但MinGW的結果可能還是會讓人感覺到奇怪:它其實是先讓最前面的2個++a執行a自增1的操作,後面的2個++aa++就照常處理,是以最終b = 3 + 3 + ...

好了,就此打住,建議不要去糾結這些細節了,因為本來就不推薦這種寫法。你隻需要知道:多個字首、字尾的自增自減一起使用時,結果具有不确定性。

總的來說,++、--是把雙刃劍,再者,它并非是編碼過程中必不可缺的,是以被Swift、Python抛棄也是正常的事。

關于彙編

經常看到有人說:彙編語言都是上古時期的程式設計語言了,沒啥用,甚至還有人說CC++這麼古老的語言,沒有任何學習價值。我個人并不贊同這些觀點。掌握好彙編,可以更好地了解代碼的本質,掃除一些基本的知識誤區​。​

因為時間和篇幅的關系,這篇文章并沒有詳細解釋每一句彙編代碼的作用。如果你對彙編感興趣,可以參考以下圖檔

之前有在B站上傳一些彙編教程,有需要的小夥伴可以向公衆号發送彙編兩字,擷取教程位址

最後的思考題

最後留一道思考題,可以将思考的結果直接留言評論

不是說Python不支援自增(++)自減(--)運算符麼,為什麼下面的Python代碼能運作成功呢?

PYTHON

a = 10

b = ++a

c = a++ + ++a

如果你特别希望我寫點什麼方面的内容,也可以留言建議,謝謝

原文位址

https://www.cnblogs.com/mjios/p/12674242.html