為什麼最近十年發明的程式語言都喜歡先變數名後型別宣告這種變數宣告方式?

時間 2022-01-13 09:09:15

1樓:雪凰

關於型別前置還是後置,從編譯器的角度來看,型別後置是更方便文法設計/編譯器開發的,但是個人認為型別前置寫起來更舒服一點。

從語言提供方來說,我覺得有兩種解釋的角度。

型別後置往往意味著需要在前面加乙個語法成分的關鍵字,當編譯器解析到這個關鍵字(var、let、func、def、type)時,就可以確定當前解析的是乙個變數還是乙個函式;

而型別前置的語言則需要《型別》《識別符號》《左小括號》才能判斷進入函式成分的分支,見到《型別》《識別符號》《等於號》才能判斷進入變數定義分支,甚至《型別》還不見得是乙個終結符,所以型別前置語言的編譯器需要look ahead n或者回溯來完成語法成分的分支決策。

對於乙個廣泛使用的語言,有大量開發者來開發編譯器,這點不便似乎不是什麼問題。但是乙個語言剛誕生之初,很可能沒有那麼多開發者來修訂文法、開發parser,對於乙個小團隊來說,降低編譯器開發可以讓他們把精力放在更重要的設計上。

對於動態型別語言,變數本身是沒有型別的,變數指向的物件才有型別,所以語言在設計之初,宣告變數是不需要型別資訊的。

但是隨著語言的發展,使用者越來越多,我們需要型別的約束來處理多人合作的問題,所以語言就需要在變數宣告的地方新增型別資訊。

因為原先是沒有型別資訊的,所以新增型別資訊最好的位置就是變數之後,這樣最符合老使用者的習慣。

TypeScript的型別後置可能就是這樣的考慮。

類似的還有Python,Python在函式的宣告裡引數和返回值型別都是可以後置地進行宣告(雖然直譯器不會檢查)。

從語言使用方來說,我個人並不認為型別後置有很大的優勢。

因為型別前置的語言,如果要利用型別推導宣告乙個變數,就需要前面加乙個關鍵字(var、auto、const)作為佔位符,這樣一來,一會兒是關鍵字,一會兒是型別名,看起來就不太整齊,有一些些混亂。

不過這個算不上太大的優點。

接下來都是我個人感受到的缺點了,主要都是從語言使用者來說的:

使用型別推導的時候,型別前置和後置是差不多的。

但是不使用型別推導的時候,型別後置就需要多寫乙個關鍵字(var、const)。

很多時候變數名和型別名差不多即可(改個大小寫、省略幾個詞),使用型別前置的語言時,輸入型別的時候IDE可以幫助補全,輸入變數名的時候IDE已經知道了型別名,就可以幫我取乙個相似的變數名,全程的體驗在IDE的輔助下很舒適。

但是變數後置的語言,你在給變數取名的時候,IDE無法幫你做類似的事情,因為它並不知道這個變數的型別(型別前置的語言使用型別推導時也會有這種問題,所以很多時候即使支援型別推導,我還是會把型別名寫出來)。

雖然GoLand在寫Go函式的引數列表的時候,可以直接輸入型別名,然後IDE會幫我在型別名前面新增乙個形參的名字,但是我感覺這樣有點反直覺,因為它新增的東西並不是在我游標所在的位置,而且IDE是直接新增上去的,並不像型別前置時它能給我幾個選項讓我來選乙個合適的。

但是總的來說,都是一些細小的差別,開發過程中最重要的部分、難點都不在於變數宣告,乙個語言的好壞主要還是體現在其它的特性上,變數的型別前置還是後置並不是乙個很大的問題(所以請允許編譯器開發者偷個小懶吧)。

2樓:

80年代的VHDL宣告訊號的方式:

signal example1 : std_logic_vector (127 downto 0);

3樓:冒泡

語義上並沒有擴充套件太多,後置能搞的,前置差不多也能搞

要說優勢,就是編譯器開發更簡單了,通過關鍵字來識別grammar,不用look ahead和回退了

go的var、func這種關鍵字當初就有人說了,是面向編譯器開發者的設計,而並不是什麼優劣之分

說白了就是發明者懶,給自己圖方便(但這不是貶義,因為上面說了前後置本來也沒有太大優劣之分,換我我也選方便的)

然而非要將其吹成哲學就……

PS:C和C++的宣告比較特殊,並非純粹的前置或後置,實際上C和C++的設計反倒是更加自洽的,只不過從人的角度不那麼直觀罷了

4樓:

更早的型別在變數名後面的語言,除了pascal 還有VBDimword

asString

型別在前面後面都是作者的個人偏好,對compiler來說沒啥差別

5樓:

記得C#的開發者訪談說過,他們原來也想把型別放在後面,但是為了和C和C++看起來一致,所以把型別放在前面了。

好像是因為如果乙個從來未學過程式設計的人類來定義乙個變數,他們會先想出變數的名稱,然後再確定變數的型別,這樣子寫起來比較順手。

6樓:freeman

不少人提到後置有利於編譯器的解析處理。

事實上,不考慮自動型別推斷時,型別前置對編譯器沒什麼難度,甚至更加輕鬆。

當然,當支援型別推斷時,由於型別省略,需要var關鍵字彌補歧義,或者其他方式消除歧義。

而後置型別一般有冒號作為型別前導,沒有歧義。但GO語言不用冒號分隔,則無此優勢,但其實也都不難處理。

所以,真正的原因,並非編譯器的麻煩,即便有細微差別也是可以忽略。

主要還是語言設計著的偏好決定。我個人喜歡C這種型別前置的風格。

無論如何,設計乙個語言,可讀性應該放在第一位,編譯器的困難放在次要地位。

比如C++的泛型使用<>就可能帶來歧義,以至於需要把語義分析的一些內容提前處理。為此GO語言的泛型一直不想使用<>表達而考慮改用(),後來又發現新的歧義而改用,實際上都不理想。因為歧義和麻煩依然存在,需要增加額外機制去避開,對編譯器並沒有更輕鬆。

但對可讀性可能不友好。

7樓:圓胖腫

你這個問題問的時間是2023年

dart發明時間是2023年年末,在十年以內dart就是型別前置的程式語言

型別無非乙個宣告,大部分語言都能實現型別的推斷比如var i = 3

不用寫清楚 Int i = 3 或者 var i:Int = 3

8樓:陀思妥耶夫女士

因為方便

讓我想起來了c like語言裡面乙個變數的閱讀技巧,

比如這個

int a;

那麼你的眼睛看到這是乙個int型別的a。

好像沒啥問題,

int* a;

你的眼睛看到這是乙個int型別的指標變數 a,然後你的腦子開始費勁地翻譯:

有個指標,指向了乙個int型別。

好像還可以。

再來乙個,

auto r=*((float*)&n);

請問r是啥。

這個時候,應該先讀變數,然後從右到左,從括號內到外閱讀。

你的眼睛看到:

這裡有個變數n,在符號表中取下來它自己的位址,把這個位址強制轉化為乙個指向flout型別的指標變數,然後再得到指向它自己的指標。

其實就是乙個cast。(型別型別轉換)

這樣讀,實際上是把眾多的型別和型別操作當作一種動作去看待,對於C語言這樣大面積使用指標的,非常方便。

還有更複雜的 。

(*void(*)()0) ();

很多程式語言設計的語法不是必然,而是基於眾多考量的結果。

建議看看《程式語言實踐之路》

9樓:軒轅羽

因為這樣比較方便。

就拿.net來說吧,要建立乙個值為1+2i的複數變數,C#這麼寫:

System

.Numerics

.Complexc1;

c1=newSystem

.Numerics

.Complex(1

,2);VB這麼寫:

DimC1

AsSystem

.Numerics

.ComplexC1=

NewSystem

.Numerics

.Complex(1

,2)VB可以寫在一行上:

DimC1

AsNew

System

.Numerics

.Complex(1

,2)C#寫在一行上就比較醜陋了:

System

.Numerics

.Complexc1=

newSystem

.Numerics

.Complex(1

,2);現在的程式語言,型別名越來越長。然而前置型別宣告需要把System.Numerics.Complex這種複雜的型別名寫兩遍,這就不如後置型別宣告了。

所以後來C#引入了這種寫法:

varc1

=new

System

.Numerics

.Complex(1

,2);這其實就是後置型別宣告,把VB的Dim改成var,把VB的As改成=。

這樣帶來的問題就是型別宣告方式不統一。比如我想宣告兩個複數,第乙個賦值1+2i,第二個不賦值:

varc1

=new

System

.Numerics

.Complex(1

,2);System

.Numerics

.Complexc2;

型別名一會兒在前面,一會兒在後面,看著不舒服。所以如果我要重新發明一種程式語言,最好就是統一把型別宣告後置。

C語言的型別宣告是前置的,那個時候沒有System.Numerics.Complex這麼複雜的型別名,型別宣告前置能節省乙個關鍵字var。

10樓:向陽

看語言設計者的口味了,我不喜歡那種玩法,挺礙眼的但是有乙個有意思的事情

如果型別集合是T

x:Tx是乙個元變數,:表示屬於,是的,就是集合裡那個屬於,即 x ∈ T

鬼知道,這是不是乙個有意思的巧合呢~

11樓:short brother

宣告語句的語法可以分三種:

保留字開頭,後面跟名稱(識別符號)和型別或表示式(var x = 123; const K = true;)

型別開頭,後面跟名稱(識別符號)和表示式(int x = 123; bool const K = true;)

名稱(識別符號)開頭,後面跟型別和表示式(x := 123; K :: true;)

現代語言會混合使用這三種宣告語法。Python用名稱開頭形式宣告一般變數,用保留字開頭宣告函式、類和import。C系語言的宣告大部分用型別開頭形式,在import上還是會使用保留字開頭形式。

三種形式都有各利弊:

每種宣告的型別需要有專門的關鍵字

語句增加了額外的關鍵字導致冗長

保留字開頭的語法鼓勵程式設計師將同一型別的宣告放置在一起,不要混合宣告和賦值。

每個宣告必有型別,這樣語法就成了型別系統的一部分。所以C語言必須要額外定義沒有型別的型別void。

C ++等語言必須使用額外的保留字(例如auto或var)來進行型別推斷。

可以用冒號後可選地填入型別表示指定型別或型別推斷。

On the Aesthetics of the Syntax of Declarations

最近十年最讓人眼前一亮的產品是什麼?

hsky 中國茶文化一直都有著相當悠久的歷史,為了更好地倡導非遺茶文化,小罐茶近年來舉辦了一系列公眾活動,引導中中國人尤其是年輕人以更加現代 時尚的方式,感受非遺和中國茶 空城 既然不限於網際網路產品的話,我已經喝了很多年的茶了,我提乙個茶品牌吧。還蠻有感悟的,時間改變的東西隨處可見,包裝就是其中之...

近十年各種商品幾乎都在漲價,為什麼內地的書價不漲?

蘇靈 書越來越貴了。中華書局,繁體豎排版 史記 原本是100左右,然後直接漲到150。技術書籍貴的嚇死人。文學類書籍則想方設法的 字大行稀,擴大邊白 再不行就從裝幀上算計,故意用厚紙,做精裝,為了提價無所不用其極。雖然說總有廣告宣稱5折 3折,其實都是爛書,真正有價值的書從來不打折,而且還動不動就脫...

經數十年發展,埃及的工業為什麼比伊朗差?

穆璉 埃及和敘利亞,葉門都是經濟較大程度上依賴油氣 埃及好點有旅遊和運河,但人也多 然而油氣又不夠多。埃及好歹政治和文化上有點影響力,沒亂起來。 老是講工業,認真研究一下工業發展到底需要啥。來來去去,水 煤炭 石油 鐵礦 銅礦 鋁礦。伊朗除了水,樣樣不缺。要知道世界第一大工業國中國,長期受缺乏石油和...