Go语言基础:变量、类型与控制流

Go语言的语法设计追求简洁,没有多余的关键字和语法糖。这篇整理Go的变量声明、基本类型和控制流语句,适合有其他语言基础的人快速上手。

变量声明

Go有两种声明变量的方式:

// var关键字,可以指定类型
var name string = "Alice"
var age int = 25
var score float64  // 零值: 0.0

// 短变量声明(只能在函数内使用)
name := "Bob"
count := 0
pi := 3.14

短变量声明 := 用得最多,编译器自动推断类型。但在函数外部(包级别)只能用var

批量声明

var (
    host   string = "localhost"
    port   int    = 8080
    debug  bool   = false
)

常量

const Pi = 3.14159
const (
    StatusOK    = 200
    StatusNotFound = 404
)

Go的常量没有类型限制,赋值给变量时才确定类型。

基本类型

// 整数
var a int     = 42    // 平台相关,64位系统上是int64
var b int32   = 100
var c uint8   = 255   // 无符号

// 浮点数
var f float64 = 3.14

// 布尔
var ok bool = true

// 字符串(不可变,UTF-8编码)
var s string = "Hello, 世界"

// byte和rune
var ch byte = 'A'       // uint8的别名
var r rune = '中'       // int32的别名,表示Unicode码点

类型转换

Go不允许隐式类型转换,必须显式:

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

// 字符串与数字转换用strconv
import "strconv"
s := strconv.Itoa(42)       // int -> string: "42"
n, err := strconv.Atoi("42") // string -> int

零值

Go的变量声明后自动有零值,不存在"未初始化"的问题:

  • 数值类型:0
  • 布尔:false
  • 字符串:""
  • 指针/切片/map/channel/函数/接口:nil

控制流

if语句

if x > 0 {
    fmt.Println("positive")
} else if x == 0 {
    fmt.Println("zero")
} else {
    fmt.Println("negative")
}

// if可以带初始化语句(变量作用域限制在if块内)
if err := doSomething(); err != nil {
    fmt.Println("error:", err)
    return
}

注意:条件不加括号,花括号不能省略。

for循环

Go只有for一种循环,没有while:

// 经典三段式
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

// 相当于while
n := 1
for n < 100 {
    n *= 2
}

// 无限循环
for {
    // break退出
}

// 遍历slice/map
nums := []int{1, 2, 3, 4, 5}
for index, value := range nums {
    fmt.Printf("index=%d, value=%d\n", index, value)
}

// 只要value不要index
for _, v := range nums {
    fmt.Println(v)
}

switch

Go的switch默认不会fall-through(不需要break):

switch day {
case "Monday":
    fmt.Println("工作日开始")
case "Friday":
    fmt.Println("快到周末了")
case "Saturday", "Sunday":
    fmt.Println("周末")
default:
    fmt.Println("普通工作日")
}

// 无条件switch(替代if-else链)
switch {
case score >= 90:
    grade = "A"
case score >= 80:
    grade = "B"
case score >= 60:
    grade = "C"
default:
    grade = "F"
}

如果真的需要fall-through,用fallthrough关键字。

小例子:猜数字游戏

把上面的知识点串起来:

package main

import (
    "fmt"
    "math/nand"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())
    target := rand.Intn(100) + 1
    fmt.Println("猜一个1-100的数字:")

    for attempts := 1; ; attempts++ {
        var guess int
        fmt.Print("> ")
        fmt.Scan(&guess)

        switch {
        case guess < target:
            fmt.Println("太小了")
        case guess > target:
            fmt.Println("太大了")
        default:
            fmt.Printf("对了!你用了%d次\n", attempts)
            return
        }
    }
}

小结

Go的变量和控制流语法非常精简——变量声明两种方式、类型转换必须显式、循环只有for。这种"少即是多"的设计让Go代码读起来很统一,团队协作时不会有太多风格争议。