语法对比基础
本模块探讨 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