Dart和Go语言特征对比
文章目录
- 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 接口