我們已經學了十五種程式語言,是時候來檢討一下他們了
C++ | python | R | Java | php | javascript | Ruby |
---|---|---|---|---|---|---|
1983 | 1991 | 1993 | 1995/5/23 | 1995/6/8 | 1995/12/4 | 1995/12/? |
C# | F# | node.js | golang | Rust | Kotlin | Dart | Typescript | Raku |
---|---|---|---|---|---|---|---|---|
2000 | 2005 | 2009/5/28 | 2009/11/10 | 2010 or 2015/5/16 | 2011 | 2011/10/10 | 2012/10/1 | 2015/12/25 |
Ruby查不到確切的時間,只知道是12月發布的,如果有人有詳細的時間再麻煩告訴我,這裡先按照日期來看高機率會在js後面
Java的時間比較不確定,因為中間還穿插改名跟可以下載的時間,這裡抓1.0a2 這個正式版本的發布日期
Rust則是早就發布了,但是1.0.0版本直到2015才上線
Raku也是早在2000年就開始有動作(當時還叫Perl6),但是正式發布是2015年
整體下來可以看到1995年是程式語言大爆發的一年,除了Ruby在15名以外,其餘都還在前十名(按照2020.08的Tobie排行)
不難看出當時很流行直譯式語言,不管是在早幾年的python還是php,js,Ruby等等都是直譯語言
大概當時追求的是開發速度吧
之後下一次的大爆發則是在2009~2012
這次反而就流行回編譯式語言了
不過這個表格只有展示我們這次教學的語言,而不是所有語言,如果有不同或相反意見都可以提出來討論
雖然使用程式碼的行數來比較完全沒有意義,但是我們還是來看看吧
C# | C++ | Dart | F# | golang | Java | Kotlin | Rust | Typescript |
---|---|---|---|---|---|---|---|---|
102 | 108 | 70 | 59 | 100 | 97 | 75 | 108 | 91 |
Javascript | node.js | php | python | R | Raku | Ruby |
---|---|---|---|---|---|---|
77 | 93 | 79 | 67 | 69 | 69 | 84 |
這些都是預設沒有註解的行數
其中Js跟php只有算上程式碼的部份,而沒有html的部份
C#行數會多應該跟{的放置位置有關(習慣上會獨自一行),因此才說用行數比較沒有任何意義
比較新的Dart跟Kotlin都算是解決了早期語言語法冗長的缺點,所以寫起來比其他語言短
其他語言都落在100行左右
意外的F#比一眾直譯式語言還少,大概是因為少見的編譯卻還使用tab作為程式碼block的區隔而不是{}
同時又有switch而不是全部使用ifelse(像是python)
編譯式語言則大多都差不多
來自C或是類似C
C++ | Java | C# | golang | Rust | |
---|---|---|---|---|---|
結構 | 方法需要事先宣告 | 使用檔案名稱作為程式碼的區隔 | namespace-class-function | package 於檔案開頭宣告 | cargo 專案管理器控管 |
引用 | #include | import | using | import() | use ; |
進入點 | int main(void) | public static void main(String[] args) | static void Main(string[] args){} | func main(){} | fn main(){} |
行尾 | ; | ; | ; | ; | |
輸入 | cin | scanner.nextLine(); | Console.ReadLine(); | fmt.Scanln(&input) | io::stdin().read_line(&mut input) |
輸出 | cout | System.out.println(""); | Console.WriteLine(""); | fmt.Println("") | println!(""); |
型別系統 | 靜態,強型別 | 靜態,強型別 | 靜態,強型別 | 靜態,強型別 | 靜態,強型別 |
方法結構 | 回傳型別 方法名稱(輸入型別 輸入變數){} | 方法形式 回傳值型別 方法名稱(參數型別 參數名稱){} | 方法類型 回傳型別 方法名稱(輸入型別 輸入變數){} | func 方法名稱(變數名稱 變數型別) (回傳變數 回傳型別){} | fn 方法名稱(變數名稱:變數型別)->回傳型別{} |
邏輯if | if (條件句){執行句} | if (條件句){執行句} | if (條件句){執行句} | if 條件句 {執行句} | if (條件句){執行句} |
邏輯switch | switch(輸入){case 條件: break;default:} | switch (輸入) {case 條件:default:} | switch (輸入){case 條件:default :} | switch 輸入 {case 條件:執行default:} | match 輸入{條件=>執行句,_=>} |
迴圈for | for (int i=0;i<10;i++){} | for (int i=0; i<10; i++) {} | for (int i=0;i<10;i++){} | for i := 0; i < 10; i++ {} | for i in 0..10 {} |
迴圈while | while(條件句){執行句} | while(條件句){執行句} | while(條件句){執行句} | for 條件句 {} | while 條件句{執行句} |
錯誤處理 | try {throw } catch() {} | try{執行句}catch(錯誤類型){} | try {throw } catch() {} | err := 錯誤回傳 | match 嘗試的結果{Ok(成功執行),Err(錯誤後執行), } |
這幾個語言算是比較接近的
C#跟Java都來自C++,go則被稱作網路世界的C語言,Rust本來就是為了讓C++更好寫而誕生
基本上因為都來自C++,因此都是靜態強型別的語言
最基本的語句if,switch,for,while,除了某幾個語言的關鍵字有換以外基本上結構都類似
但是除此之外各個語言在結構上都走出自己的路,結構上就各有不同,函式庫引用的方式也不相同
另外看可以看到Java跟C#因為模仿C++的原因都在方法的宣告上都沒有關鍵字,較為後期的golang跟Rust反而有
來自js或可編譯成js
Dart | Kotlin | Javascript | Typescript | node.js | |
---|---|---|---|---|---|
結構 | 編譯式 | 編譯式 | 直譯式 | 直譯式 | 直譯式 |
引用 | import ''; | import | html引用 | import | var 引用名稱 = require('套件名稱'); |
進入點 | void main() {} | fun main() {} | 沒有進入點 | 沒有進入點 | 沒有進入點 |
行尾 | ; | ;可有可無,建議有 | ;可有可無,建議有 | ;可有可無,建議有 | |
輸入 | stdin.readLineSync(); | readLine() | html輸入 | createInterface.question() | createInterface.question() |
輸出 | print / stdout.writeln("") | println("") | html輸出 | console.log("") | console.log("") |
型別系統 | 靜態,強型別 | 靜態,強型別 | 動態,弱型別 | 靜態,強型別 | 動態,弱型別 |
方法結構 | 回傳型別 方法名稱(輸入型別 輸入變數){} | fun 方法名稱(變數名稱:變數型別):回傳值型別{} | function 方法名稱(變數名稱) {} | const 方法名稱 = (變數名稱:變數型別):回傳型別=>{} | function 方法名稱(變數名稱) {} |
邏輯if | if (條件句){執行句} | if (條件句){執行句} | if (條件句){執行句} | if (條件句){執行句} | if (條件句){執行句} |
邏輯switch | switch(輸入){case 條件: 執行 break;default:} | when (輸入){條件->{}else ->} | switch(輸入){case 條件: 執行 break;default: } | switch (輸入){case 條件:default: } | switch(輸入){case 條件: 執行 break;default: } |
迴圈for | for (int i=0;i<10;i++){} | for(int i = 0; i < 10; i++) {} | for (let i = 0; i < 10; i++) {} | for (let i = 0; i < 10; i++) {} | for (let i = 0; i < 10; i++) {} |
迴圈while | while(條件句){執行句} | while(條件句){執行句} | while(條件句){執行句} | while(條件句){執行句} | while(條件句){執行句} |
錯誤處理 | try{執行句}catch(錯誤類型){} | try{執行句}catch(錯誤類型){} | try{執行句}catch(錯誤類型){} | try{執行句}catch(錯誤類型){} | try{執行句}catch(錯誤類型){} |
基本上node.js跟js是一模一樣的,差別在於一個在瀏覽器上執行一個在伺服端執行
js,ts,node.js都可以使用ES6的寫法,也就是function可以寫成const,基本上語法沒有什麼區分
差別在於TS會要求你事先定義好型別,並且沒辦法隨意轉型
node.js使用函式庫還可以配合套件管理器npm
而Dart及Kotlin雖然都是手機的前端語言,並且都能編譯成js,但實際上兩者的市場是有所區隔的
Dart更想要跨平台,而Kotlin更想要取代Java
Perl6/Raku Python Ruby 這三個常常被拿出來比較的語言
python | Ruby | Raku | |
---|---|---|---|
結構 | 直譯式 | 直譯式 | 直譯式 |
引用 | import | require "" | use |
進入點 | 程式碼開頭 | 程式碼開頭 | 程式碼開頭 |
行尾 | ; | ||
輸入 | input("") | gets | get |
輸出 | print("") | puts | say |
型別系統 | 動態,強型別 | 動態,強型別 | 動態,弱型別 |
方法結構 | def 方法名稱(變數名稱) | def 方法名稱(變數名稱)end | sub 方法名稱(變數名稱){} |
邏輯if | if 條件句(tab)執行句 | if 條件句執行句end | if (條件句){執行句} |
邏輯switch | - | case 輸入 when 條件elseend | give 輸入{when 條件 {}default {}} |
迴圈for | for i in range(10):(tab)執行句 | for i in 0...10end | loop (my $i =0;$i<10;$i++){} |
迴圈while | while 條件句:(tab)執行句 | while 條件句執行句end | while 條件句{} |
錯誤處理 | try:(tab)執行句except 錯誤類型:(tab)錯誤執行 | begin 執行句 rescue 錯誤執行 end | ㄎtry { 執行句 CATCH {錯誤執行} } |
三個語言都是直譯,動態的語言
整體而言Ruby比較像是兩者的集合體,語法具有兩家所長
不過這並不代表Ruby就一定比其他兩者優秀
語言還是需要發揮在自己適合的地方
F# | php | R | |
---|---|---|---|
結構 | 接近直譯語言 | 與html混雜 | Rsudio是你的好夥伴 |
引用 | open | require(''); | library() |
進入點 | [] | - | - |
行尾 | ; | ||
輸入 | Console.ReadLine(); | html輸入 | - |
輸出 | printfn "" | echo | Rstudio |
型別系統 | 靜態,強型別 | 動態,弱型別 | 動態,強型別 |
方法結構 | let 方法名稱 (輸入變數:輸入型別):回傳型別 = | function 方法名稱(變數名稱(){} | 方法名稱 <- function(變數名稱){} |
邏輯if | if 條件句 then 執行句 elif 條件句 then 執行句 else | if (條件句){執行句} | if (條件句){執行句} |
邏輯switch | match input with|模式 -> 執行| _ -> | switch (輸入){case 條件:default :} | switch(輸入,條件1=執行句,條件2=執行句) |
迴圈for | for i = 0 to 10 do | for ($i=0; $i<10; $i++) {} | for (i in 0:10){} |
迴圈while | while 條件句 do 執行句 | while(條件句){執行句} | while(條件句){執行句} |
錯誤處理 | try 執行句 with |錯誤類型 ->執行句 | try {執行句} catch (錯誤類型) {錯誤執行} | tryCatch({ 執行句 }, error = function(e) {錯誤處理 } |
這三個語言有著自己擅長的地方
因此在這邊作為比較沒有意義,單純將剩下沒表格的語言放進來
如果你到現在還是沒辦法決定自己要學的語言的話,以下可以當作參考
php,Ruby
使用成熟的架構絕對沒有錯,php具有成熟的LAMP,Ruby具有成熟的Ruby on Rails
兩者都有相當活絡的社群
我要走網路架構,未來希望可以進資訊產業
相信google嗎?
golang
可以給golang一點機會,發展十年就進入TOBIE前20名,未來指日可待
不相信google?
別這樣,給golang一點機會嘛
不想?好吧,你可以看看下面幾種語言
沒打算走網路架構,只想做單純的桌面程式
喜歡微軟?
C#
地表最強IDE Virtual Studio將會為你搞定一切
不喜歡微軟?
Java
JAVA歡迎你,重點他還可以跨平台
AI好像很紅?
python,C++
除非你有一個很會C++的朋友,不然我建議你從python入手,發展成熟的TensorFlow會是你的好選擇
我想寫網頁
javascript,Typescript
端看你喜歡強型別還是弱型別
目前已經幾乎沒有人會直接寫js了,如果你已經選擇了網站前端,就來走框架吧
喜歡弱型別就走js,Vue跟React都可以選
喜歡強型別的就走Typescript,Angular是跟前面兩個框架齊名的三大框架之一
我想寫手機APP
Android?
Java,Kotlin
反正就是Java系列
iOS?
你只有Swift可以選,除非你想不開去學Objective-C
跨平台?
Dart的Flutter框架或是js的React-Native框架
我想作為研究的工具
R或是F#
喜歡微軟就F#,不喜歡就R
當然,python也是個好選擇
總之別選Matlab就是了
就.....單純想學
python
學會了你想幹麻就可以幹麻
我想成為新世界的神
C/C++
你掌握的他就等於在中土世界掌握了魔戒
有不同的意見都可以提出討論
有錯誤的地方請盡量提出,會盡快修正