环境配置篇:从JDK到GoRoot
1. 安装对比
- Java:安装JDK → 配置JAVA_HOME → javac验证
 - Go:官网下载.msi → 自动设置GOROOT → go version验证
 
2. VS Code配置差异
# Java环境
安装Extension Pack for Java
需要配置Maven路径
# Go环境
安装Go扩展(Go Team at Google)
自动安装gopls等工具链
3. 项目初始化实战
// Java项目结构(Maven)
src/
  main/
    java/
      com/example/
        Main.java
pom.xml
// Go项目结构
go.mod       // 类似pom.xml
main.go
└── utils/   // 自定义包
    └── math.go
基础语法篇:当Java遇上Go
1. 变量声明对照表
场景  | Java写法  | Go写法  | 核心差异  | 
显式声明  | int count = 10;  | var count int = 10  | 类型后置  | 
类型推断  | var list = new ArrayList<>()  | list := []string{}  | 短变量声明  | 
多变量声明  | 不支持  | a, b := 1, "hello"  | 元组式赋值  | 
2. 数组与切片(关键差异点)
// Java数组 vs ArrayList
int[] arr = {1,2,3};                  // 定长
ArrayList list = new ArrayList<>(); // 动态扩容
list.add(4);
 // Go数组 vs 切片
arr := [3]int{1,2,3}        // 定长数组
slice := []int{1,2,3}       // 动态切片
slice = append(slice, 4)    // 扩容需重新赋值
// 内存细节:切片底层引用数组
header := slice[:2]         // 创建新切片头(共享底层数组)
3. 流程控制对比
循环结构:
// Java三剑客
for (int i=0; i<5; i++) { /*...*/ }
while(condition) { /*...*/ }
do { /*...*/ } while(condition);
// Go的万能for
for i := 0; i < 5; i++ { /* 传统循环 */ }
for condition { /* while替代 */ }
for { /* 无限循环 */ break }
Switch陷阱:
// Java需要break
switch (x) {
  case 1: 
    System.out.println("one");
    break; // 必须显式阻断
  default:
    System.out.println("other");
}
// Go默认不穿透
switch x {
case 1:
    fmt.Println("one") // 自动break
case 2,3:             // 多值匹配
    fmt.Println("two or three")
default:
    fmt.Println("other")
}
函数篇:从方法到一等公民
1. 基础函数差异
// Java方法
public static int add(int a, int b) {
    return a + b;
}
// 单返回值
// 必须属于某个类
// Go函数
func add(a, b int) int {
    return a + b
}
// 独立存在
// 支持多返回值
2. 多返回值革命
// 文件读取的典型模式
func readFile(path string) ([]byte, error) {
    content, err := os.ReadFile(path)
    return content, err
}
// 调用时显式处理错误
data, err := readFile("test.txt")
if err != nil {
    log.Fatal(err)
}
3. 函数式编程初探
// Java Lambda
List nums = Arrays.asList(1,2,3);
nums.stream()
    .map(x -> x * 2)
    .forEach(System.out::println);
 // Go匿名函数
nums := []int{1, 2, 3}
// 立即执行函数
func() {
    fmt.Println("立即执行!")
}()
// 函数作为参数
transform := func(x int) int { return x * 2 }
for _, n := range nums {
    fmt.Println(transform(n))
}
避坑指南:Java转Go常见错误
- 分号依赖:Go编译器自动加分号,行尾不能随意换行
 
   // 错误写法
   return 
   result // 实际返回的是空值
   // 正确写法
   return result
- 作用域误解:
 
   if num := 10; num > 5 {
       fmt.Println(num) // 正确
   }
   fmt.Println(num) // 编译错误!num只在if块内有效
- 值传递陷阱:
 
   func updateSlice(s []int) {
       s[0] = 9       // 修改底层数组
       s = append(s, 4) // 创建新切片
   }
   // 调用者看到的切片长度不变!
上篇实战作业
- 将Java版冒泡排序改写为Go实现
 - 实现一个多返回值函数:计算圆面积和周长
 - 用Go重写Java工具类中的字符串处理方法
 
(提示:Go标准库常用包 - strings, strconv, math)
下篇预告:中篇将深入Go的"结构体+接口"面向对象模型,揭秘defer的黑魔法,并对比Go Module与Maven的依赖管理哲学。
