文章目錄
- Dart 和 Go 語法對照表
- 字符串常用方法對照
- 列表(數組/切片)常用方法對照
- Map (字典/哈希表) 使用對照
- IO 操作對照
- 文件操作
- 標準輸入輸出
- 網絡IO
- 主要差異說明
有同事說,我前端用Flutter,后端用Golang,都師出名門。但兩個語言還是老打架,總不能芝麻蒜皮的事情都請教AI吧。腦子里多多少少還是裝點東西比較好。
Dart 和 Go 語法對照表
以下是 Dart 和 Go 語言在主要語法要素上的對比:
語法要素 | Dart 語法 | Go 語法 |
---|---|---|
基本數據類型 | ||
整數 | int (64位) | int , int8 , int16 , int32 , int64 |
浮點數 | double | float32 , float64 |
布爾值 | bool | bool |
字符串 | String | string |
動態類型 | dynamic , var , Object | interface{} (Go 1.18+ 可用 any ) |
變量定義 | ||
顯式類型聲明 | int x = 10; | var x int = 10 或 x := 10 |
類型推斷 | var x = 10; 或 final x = 10; | x := 10 |
常量 | const x = 10; 或 final x = 10; | const x = 10 |
函數定義 | ||
基本函數 | int add(int a, int b) { return a + b; } | func add(a int, b int) int { return a + b } |
匿名函數 | (a, b) => a + b; | func(a, b int) int { return a + b } |
類定義 | ||
類聲明 | class Person { ... } | type Person struct { ... } |
構造函數 | Person(this.name, this.age); | Go 沒有構造函數,通常用 NewPerson() 函數 |
方法定義 | void sayHello() { print('Hello'); } | func (p Person) SayHello() { fmt.Println("Hello") } |
繼承/接口 | class Student extends Person implements Learner { ... } | Go 使用組合和接口: type Student struct { Person } + type Learner interface { ... } |
控制結構 | ||
if 語句 | if (x > 0) { ... } else { ... } | if x > 0 { ... } else { ... } |
for 循環 | for (var i = 0; i < 10; i++) { ... } | for i := 0; i < 10; i++ { ... } |
while 循環 | while (x > 0) { ... } | for x > 0 { ... } |
range 循環 | for (var item in list) { ... } | for index, item := range list { ... } |
switch 語句 | switch (x) { case 1: ... default: ... } | switch x { case 1: ... default: ... } |
集合類型 | ||
數組/切片 | List<int> list = [1, 2, 3]; | slice := []int{1, 2, 3} |
字典 | Map<String, int> map = {'a': 1, 'b': 2}; | map := map[string]int{"a": 1, "b": 2} |
錯誤處理 | try { ... } catch (e) { ... } | result, err := someFunc(); if err != nil { ... } |
并發 | Future , async/await , Isolate | goroutine , channel , sync 包 |
包/模塊管理 | import 'package:path/path.dart'; | import "path/to/package" |
空安全 | 有 (非空類型 String , 可空類型 String? ) | 無 (但有 nil) |
字符串常用方法對照
操作描述 | Dart 字符串方法 | Go 字符串方法 |
---|---|---|
長度 | str.length | len(str) |
是否為空 | str.isEmpty 或 str.isNotEmpty | len(str) == 0 |
拼接 | str1 + str2 或 '$str1$str2' | str1 + str2 或 strings.Join([]string{str1, str2}, "") |
分割 | str.split(',') | strings.Split(str, ",") |
子串 | str.substring(start, [end]) | str[start:end] |
包含 | str.contains('substr') | strings.Contains(str, "substr") |
查找位置 | str.indexOf('substr') | strings.Index(str, "substr") |
大小寫轉換 | str.toUpperCase() / str.toLowerCase() | strings.ToUpper(str) / strings.ToLower(str) |
去除空格 | str.trim() / str.trimLeft() / str.trimRight() | strings.TrimSpace(str) / strings.TrimLeft / strings.TrimRight |
替換 | str.replaceAll('old', 'new') | strings.ReplaceAll(str, "old", "new") |
前綴/后綴檢查 | str.startsWith('prefix') / str.endsWith('suffix') | strings.HasPrefix(str, "prefix") / strings.HasSuffix(str, "suffix") |
重復 | str * n (如 'a' * 3 得到 'aaa' ) | strings.Repeat(str, n) |
格式化 | 'Name: $name, Age: ${age}' | fmt.Sprintf("Name: %s, Age: %d", name, age) |
比較 | str1.compareTo(str2) | strings.Compare(str1, str2) |
UTF-8 操作 | str.runes (獲取 Unicode 碼點迭代器) | []rune(str) (轉換為 rune 切片) |
列表(數組/切片)常用方法對照
操作描述 | Dart List 方法 | Go Slice/Array 方法 |
---|---|---|
初始化 | var list = [1, 2, 3]; 或 List<int> list = [1, 2, 3]; | slice := []int{1, 2, 3} 或 var array [3]int = [3]int{1, 2, 3} |
長度 | list.length | len(slice) |
是否為空 | list.isEmpty 或 list.isNotEmpty | len(slice) == 0 |
添加元素 | list.add(item) 或 list.addAll([item1, item2]) | slice = append(slice, item) 或 slice = append(slice, item1, item2) |
插入元素 | list.insert(index, item) 或 list.insertAll(index, [item1, item2]) | 需手動實現: slice = append(slice[:i], append([]T{item}, slice[i:]...)...) |
刪除元素 | list.remove(item) 或 list.removeAt(index) | slice = append(slice[:i], slice[i+1:]...) |
清空 | list.clear() | slice = slice[:0] |
查找索引 | list.indexOf(item) | 需手動遍歷或使用 sort.Search (排序后) |
包含檢查 | list.contains(item) | 需手動遍歷 |
排序 | list.sort() 或 list.sort((a, b) => a.compareTo(b)) | sort.Slice(slice, func(i, j int) bool { return slice[i] < slice[j] }) |
反轉 | list.reversed.toList() | 需手動實現或使用 sort.Reverse |
切片/子列表 | list.sublist(start, [end]) | slice[start:end] |
連接列表 | list1 + list2 或 [...list1, ...list2] | append(list1, list2...) |
映射 | list.map((item) => item * 2).toList() | 需手動遍歷或使用泛型函數 |
過濾 | list.where((item) => item > 2).toList() | 需手動遍歷過濾 |
遍歷 | list.forEach((item) { ... }) | for index, item := range slice { ... } |
折疊/歸約 | list.fold(initial, (prev, item) => prev + item) | 需手動遍歷實現 |
元素檢查 | list.every((item) => item > 0) / list.any((item) => item > 0) | 需手動遍歷實現 |
去重 | list.toSet().toList() | 需手動實現(使用 map) |
填充 | List.filled(3, 0) | 需手動初始化 |
生成范圍列表 | List.generate(5, (index) => index * 2) | 需手動實現 |
Map (字典/哈希表) 使用對照
操作描述 | Dart Map 用法 | Go Map 用法 |
---|---|---|
初始化 | var map = {'a': 1, 'b': 2}; Map<String, int> map = {'a': 1, 'b': 2}; | m := map[string]int{"a": 1, "b": 2} |
新建空Map | var map = {}; Map<String, int> map = {}; | m := make(map[string]int) |
添加/更新元素 | map['key'] = value | m["key"] = value |
獲取元素 | var value = map['key']; (不存在返回null) | value := m["key"] (不存在返回零值)value, exists := m["key"] |
刪除元素 | map.remove('key'); | delete(m, "key") |
檢查鍵是否存在 | map.containsKey('key') | _, exists := m["key"] |
長度 | map.length | len(m) |
是否為空 | map.isEmpty / map.isNotEmpty | len(m) == 0 |
遍歷 | map.forEach((k, v) { ... }); for (var k in map.keys) { ... } | for k, v := range m { ... } |
獲取所有鍵 | map.keys.toList() | 需手動收集:keys := make([]string, 0, len(m)) for k := range m { keys = append(keys, k) } |
獲取所有值 | map.values.toList() | 類似獲取鍵的方式 |
合并Map | {...map1, ...map2} map1.addAll(map2) | 需手動遍歷實現 |
清空Map | map.clear() | 需重新make或遍歷delete |
不可變Map | Map.unmodifiable({'a': 1}) | 無內置支持,需自定義實現 |
IO 操作對照
文件操作
操作描述 | Dart 文件操作 | Go 文件操作 |
---|---|---|
讀取整個文件 | dart<br>var content = await File('path.txt').readAsString();<br> | go<br>data, err := os.ReadFile("path.txt")<br> |
逐行讀取 | dart<br>var lines = await File('path.txt').readAsLines();<br> | go<br>file, _ := os.Open("path.txt")<br>scanner := bufio.NewScanner(file)<br>for scanner.Scan() { line := scanner.Text() }<br> |
寫入文件 | dart<br>await File('path.txt').writeAsString('content');<br> | go<br>err := os.WriteFile("path.txt", []byte("content"), 0644)<br> |
追加寫入 | dart<br>var file = await File('path.txt').open(mode: FileMode.append);<br>await file.writeString('content');<br> | go<br>file, _ := os.OpenFile("path.txt", os.O_APPEND|os.O_WRONLY, 0644)<br>file.WriteString("content")<br> |
檢查文件是否存在 | dart<br>var exists = await File('path.txt').exists();<br> | go<br>_, err := os.Stat("path.txt")<br>exists := !os.IsNotExist(err)<br> |
刪除文件 | dart<br>await File('path.txt').delete();<br> | go<br>err := os.Remove("path.txt")<br> |
目錄操作 | dart<br>var dir = Directory('path');<br>await dir.create();<br>var list = dir.list();<br> | go<br>os.Mkdir("path", 0755)<br>files, _ := os.ReadDir("path")<br> |
標準輸入輸出
操作描述 | Dart 標準IO | Go 標準IO |
---|---|---|
打印輸出 | print('Hello'); stdout.writeln('Hello'); | fmt.Print("Hello") fmt.Println("Hello") |
格式化輸出 | print('Name: $name, Age: $age'); | fmt.Printf("Name: %s, Age: %d", name, age) |
讀取輸入 | dart<br>var input = stdin.readLineSync();<br> | go<br>var input string<br>fmt.Scanln(&input)<br> |
讀取數字輸入 | dart<br>var num = int.parse(stdin.readLineSync()!);<br> | go<br>var num int<br>fmt.Scanf("%d", &num)<br> |
網絡IO
操作描述 | Dart 網絡IO | Go 網絡IO |
---|---|---|
HTTP GET請求 | dart<br>var response = await http.get(Uri.parse('https://example.com'));<br>var body = response.body;<br> | go<br>resp, _ := http.Get("https://example.com")<br>body, _ := io.ReadAll(resp.Body)<br> |
HTTP POST請求 | dart<br>var response = await http.post(<br> Uri.parse('https://example.com'),<br> body: {'key': 'value'}<br>);<br> | go<br>resp, _ := http.PostForm("https://example.com", url.Values{"key": {"value"}})<br> |
創建HTTP服務器 | dart<br>var server = await HttpServer.bind('localhost', 8080);<br>await for (var request in server) {<br> request.response.write('Hello');<br> await request.response.close();<br>}<br> | go<br>http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {<br> fmt.Fprint(w, "Hello")<br>})<br>http.ListenAndServe(":8080", nil)<br> |
主要差異說明
-
類型系統:
- Dart 是面向對象的語言,支持類和繼承
- Go 是面向接口的語言,使用組合而非繼承
-
并發模型:
- Dart 使用
async/await
和Isolate
- Go 使用
goroutine
和channel
- Dart 使用
-
錯誤處理:
- Dart 使用異常機制 (
try/catch
) - Go 使用顯式錯誤返回值
- Dart 使用異常機制 (
-
構造函數:
- Dart 有專門的構造函數語法
- Go 通常使用工廠函數 (如
NewPerson()
) 來創建結構體實例
-
泛型:
- Dart 2.0+ 支持泛型
- Go 1.18+ 支持泛型
-
空安全:
- Dart 2.12+ 有健全的空安全
- Go 沒有內置的空安全機制
-
語法風格:
- Dart 使用分號和大括號,類似 Java/JavaScript
- Go 也使用大括號,但可以省略分號,語法更簡潔
-
字符串處理:
- Dart 的字符串方法是內置的成員方法
- Go 的字符串操作大多在
strings
包中提供
-
列表/切片操作:
- Dart 的 List 提供了豐富的高階方法(map/filter/reduce等)
- Go 的切片操作更底層,許多功能需要手動實現或使用標準庫
-
不可變性:
- Dart 有不可變列表:
List.unmodifiable()
- Go 的切片總是可變的
- Dart 有不可變列表:
-
泛型支持:
- Dart 2.0+ 全面支持泛型,列表方法可以類型安全地使用
- Go 1.18+ 支持泛型,但標準庫的許多方法還未完全適配
-
鏈式調用:
- Dart 支持方法鏈式調用(如
list.map(...).where(...).toList()
) - Go 通常需要分步操作或自定義函數
- Dart 支持方法鏈式調用(如
這個對照表涵蓋了兩1. Map 差異:
- Dart 的 Map 是泛型類,有豐富的內置方法
- Go 的 map 是內置類型,操作更基礎,部分功能需手動實現
- Go 的 map 值訪問會返回零值,Dart 返回 null
-
IO 差異:
- Dart 的 IO 操作通常是異步的(使用 Future/await)
- Go 的 IO 操作通常是同步的,但可以通過 goroutine 實現并發
- Dart 的 core 庫包含基本 IO,網絡需要 http 包
- Go 的 IO 操作分散在 os, io, bufio, net/http 等包中
-
錯誤處理:
- Dart 使用 try-catch 處理異常
- Go 使用多返回值模式(error 值)
-
文件路徑:
- Dart 可以使用 path 包處理跨平臺路徑
- Go 的 path/filepath 包提供類似功能
-
流處理:
- Dart 有 Stream 和 StreamTransformer 支持
- Go 使用 io.Reader 和 io.Writer 接口