語法對比基礎
本模組探討 JavaScript 和 Go 之間的基本語法差異,涵蓋變數宣告、控制流、函數、資料型別和其他核心語言結構。
變數宣告和型別系統
JavaScript 使用動態型別,變數型別在執行時確定,而 Go 使用靜態型別,具有型別推斷能力。
變數宣告方式對比
| 宣告方式 | JavaScript | Go | 說明 |
|---|---|---|---|
| 變數宣告 | let x = 10; | x := 10 | 型別推斷,區域作用域 |
| 常數宣告 | const x = 10; | const x = 10 | 不可重新賦值 |
| 顯式型別宣告 | let x: number = 10; (TypeScript) | var x int = 10 | 明確指定型別 |
| 零值初始化 | let x; (undefined) | var x int (0) | 預設值初始化 |
| 多重賦值 | let a = 1, b = 2; | a, b := 1, 2 | 同時宣告多個變數 |
| 區塊級作用域 | { let x = 10; } | { x := 10 } | 限制變數作用域 |
| 函數作用域 | var x = 10; | var x = 10 | 提升到函數頂部 |
型別推斷對比
| 特性 | JavaScript | Go | 說明 |
|---|---|---|---|
| 數字型別 | number (64位浮點) | int, int8, int16, int32, int64, uint, float32, float64 | Go 有精確的整數型別 |
| 字串型別 | string | string | 都支援 UTF-8 |
| 布林型別 | boolean | bool | 相同概念 |
| 陣列型別 | Array (動態) | [n]T (固定), []T (切片) | Go 區分陣列和切片 |
| 物件型別 | Object | struct, map | Go 使用結構體作為主要資料結構 |
| 空值 | null, undefined | nil | Go 統一使用 nil |
| 型別檢查 | 執行時 | 編譯時 | Go 編譯時型別安全 |
正在載入編輯器...
控制流語句對比
兩種語言都支援類似的控制流結構,但語法和約定不同。
If/Else 語句
正在載入編輯器...
For 迴圈
正在載入編輯器...
函數定義和呼叫
Go 函數需要顯式的返回型別,與 JavaScript 函數的語法不同。
正在載入編輯器...
資料型別和結構
Go 有豐富的內建型別和結構,與 JavaScript 有顯著差異。
資料型別詳細對比
| 資料型別 | JavaScript | Go | 零值 | 說明 |
|---|---|---|---|---|
| 整數 | number | int, int8, int16, int32, int64 | 0 | Go 有精確的整數大小 |
| 無符號整數 | 無 | uint, uint8, uint16, uint32, uint64 | 0 | Go 支援無符號整數 |
| 浮點數 | number | float32, float64 | 0.0 | Go 區分單雙精度 |
| 複數 | 無 | complex64, complex128 | 0+0i | Go 內建複數支援 |
| 字串 | string | string | "" | 都支援 UTF-8 編碼 |
| 布林值 | boolean | bool | false | 相同概念 |
| 空值 | null, undefined | nil | nil | Go 統一使用 nil |
| 陣列 | Array | [n]T | [0,0,0] | Go 陣列固定大小 |
| 動態陣列 | Array | []T (切片) | nil | Go 切片是動態的 |
| 物件 | Object | struct | 結構體零值 | Go 結構體有定義的結構 |
| 映射 | Map | map[K]V | nil | 鍵值對儲存 |
| 集合 | Set | 無內建 | - | Go 可用 map 模擬 |
| 函數 | Function | func | nil | 函數型別 |
| 通道 | 無 | chan T | nil | Go 併發通訊 |
| 介面 | 無 | interface{} | nil | Go 多型支援 |
| 指標 | 無 | *T | nil | Go 記憶體位址參照 |
正在載入編輯器...
作用域和生命週期
兩種語言都有塊作用域,但 Go 的作用域規則更顯式和一致。
正在載入編輯器...
錯誤處理
JavaScript 使用 try-catch 進行異常處理,而 Go 使用顯式的錯誤返回值。
正在載入編輯器...
變數作用域對比
JavaScript 和 Go 在變數作用域方面有一些重要差異。
作用域規則對比
| 作用域類型 | JavaScript | Go | 說明 |
|---|---|---|---|
| 全域作用域 | var x = 10; | var x = 10 (套件級別) | 都支援全域變數 |
| 函數作用域 | function() { var x = 10; } | func() { x := 10 } | 函數內部變數 |
| 區塊作用域 | { let x = 10; } | { x := 10 } | 花括號內變數 |
| 提升行為 | var 提升到函數頂部 | 無提升 | Go 變數必須在使用前宣告 |
| 閉包支援 | 完全支援 | 完全支援 | 都支援函數閉包 |
| 變數遮蔽 | 支援 | 支援 | 內層變數遮蔽外層 |
| 迴圈變數 | for (let i = 0; ...) | for i := 0; ... | 迴圈計數器作用域 |
變數生命週期對比
| 生命週期特性 | JavaScript | Go | 說明 |
|---|---|---|---|
| 垃圾回收 | 自動 | 自動 | 都使用垃圾回收 |
| 記憶體管理 | 自動 | 自動 | 開發者無需手動管理 |
| 變數銷毀 | 作用域結束時 | 作用域結束時 | 自動清理 |
| 參照計數 | 自動 | 自動 | 參照計數管理 |
| 記憶體洩漏 | 閉包可能導致 | 閉包可能導致 | 需要注意循環參照 |
基本資料型別對比
Go 有全面的內建型別,每種型別都有特定用途。
| JavaScript 型別 | Go 等價型別 | 說明 |
|---|---|---|
number | int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, complex64, complex128 | Go 有特定的整數大小 |
string | string | 預設 UTF-8 編碼 |
boolean | bool | 相同概念 |
null | nil | 用於指標、介面、切片、map、通道 |
undefined | 無直接等價 | 通常用 nil 或零值表示 |
object | struct, map[string]interface{} | 結構體是分組資料的主要方式 |
array | [n]T (陣列), []T (切片) | 陣列固定大小,切片動態 |
symbol | 無直接等價 | Go 型別系統中不需要 |
bigint | int64, uint64, 或外部套件 | 用於任意精度 |
運算子和表達式
大多數算子相似,但 Go 在語法和行為上有一些差異。
正在載入編輯器...
練習題:
- 解釋 Go 中
array和slice型別的區別,以及何時使用每種型別。 - 編寫一個 Go 函數,接受整數切片並返回總和和平均值,演示多個返回值。
- Go 的錯誤處理與 JavaScript 的異常處理有何不同?提供兩種方法的範例。
- 建立一個 Go 結構體來表示
Person,包含姓名、年齡和郵箱欄位,然後編寫一個函數來驗證人員資料。
專案想法:
- 在 Go 中建構一個簡單的計算器程式,可以執行基本算術運算,演示函數使用、錯誤處理和使用者輸入處理。與 JavaScript 等效版本進行比較。
下一步:
- 學習 Go 的套件系統和模組管理
- 理解 Go 的型別系統和介面
- 探索 Go 強大的並發特性:goroutines 和 channels