学习Go语言:循环和条件语句

for循环

我们首先来看for循环

go 复制代码
i := 1
for i <= 3 {
    fmt.Println(i)
    i = i + 1
}

它从1开始,每次迭代打印i的当前值,并将i递增1。当i达到4时循环停止。

虽然在循环外声明i是可行的,但更常见的做法是在循环初始化时声明它。

go 复制代码
for j := 0; j < 3; j++ {
    fmt.Println(j)
}

这个第二个循环更接近我预期的形式。变量j在循环内声明,从0开始,每次迭代后递增,并在j达到3时停止。每次迭代打印j的值。

go 复制代码
for i := range 3 {
    fmt.Println("range", i)
}

这个循环迭代3次,i依次取值0、1和2。本质上,这与前一个循环相同,只是以更简洁和标准的方式实现。

go 复制代码
for {
    fmt.Println("loop")
    break
}

现在事情变得有趣了。这个循环没有停止条件 ,它会无限运行,除非我们在Println后立即使用break,在它运行后立即停止。

go 复制代码
for n := range 6 {
    if n%2 == 0 {
        continue
    }
    fmt.Println(n)
}

这个例子很巧妙。我们在这里看到了多个新东西 :取模运算符(%)、ifcontinue关键字。

这个循环从0数到5。它使用n % 2 == 0检查n是否为偶数。如果是,continue跳过当前迭代的剩余部分并移动到下一个数字。否则,它打印n

简而言之,它只打印范围内的奇数

条件语句

条件语句是任何编程语言的基石,允许我们根据输入变量进行分支判断。主要有两种条件块:if/else语句和switch语句,让我们来探索它们。

if/else语句

如果语句归结为评估为truefalse的表达式;如果表达式为true,则执行某些操作,否则执行其他操作。

go 复制代码
if 7%2 == 0 {
    fmt.Println("7是偶数")
} else {
    fmt.Println("7是奇数")
}

我们的老朋友取模运算符又回来了。在这个例子中,我们检查数字7是否为偶数,并打印它是否为偶数。

go 复制代码
if 8%4 == 0 {
    fmt.Println("8能被4整除")
}

这基本上是一个相同的例子,但展示了else部分不是必需的。

go 复制代码
if 8%2 == 0 || 7%2 == 0 {
    fmt.Println("8或7中有一个是偶数")
}

这里我们有一个条件,如果你使用过其他语言,这会很熟悉,允许如果任一条件为真时执行if语句。

go 复制代码
if num := 9; num < 0 {
    fmt.Println(num, "是负数")
} else if num < 10 {
    fmt.Println(num, "有一位数字")
} else {
    fmt.Println(num, "有多个数字")
}

最后,我们有一个else if示例。这允许我们对输入进行多个条件检查并执行第一个为真的条件。

go 复制代码
num := 9

if num < 0 {
    fmt.Println(num, "是负数")
} else if num < 10 {
    fmt.Println(num, "有一位数字")
} else {
    fmt.Println(num, "有多个数字")
}

Go没有三元运算符,如果你在其他语言中习惯于使用它,这可能会有些遗憾。

switch语句

switch语句虽然类似于if/else块,但有些不同。

让我们来分析这个示例。

go 复制代码
i := 2
fmt.Print("将", i, "写成")
switch i {
case 1:
    fmt.Println("一")
case 2:
    fmt.Println("二")
case 3:
    fmt.Println("三")
}

第一个示例中,他们已经偷偷加入了一些新东西。fmt上的Print方法打印时不换行,我们可以用逗号分隔值将它们连接在一起。

除了这一点,这个示例非常简单,声明i并检查i是否为1、2或3,如果是,打印出对应的单词。

go 复制代码
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
    fmt.Println("今天是周末")
default:
    fmt.Println("今天是工作日")
}

在这里,我们看到了对time包的首次使用。

go 复制代码
t := time.Now()
switch {
case t.Hour() < 12:
    fmt.Println("现在是中午之前")
default:
    fmt.Println("现在是中午之后")
}

这个示例与前一个类似,只是我们将time.Now()调用存储为一个变量,并且没有在switch中传递表达式。

go 复制代码
whatAmI := func(i interface{}) {
    switch t := i.(type) {
    case bool:
        fmt.Println("我是一个布尔值")
    case int:
        fmt.Println("我是一个整数")
    default:
        fmt.Printf("不知道类型%T\n", t)
    }
}

whatAmI(true)
whatAmI(1)
whatAmI("嘿")

首先,我们有一个名为whatAmI的变量,它接受i作为interface{}func

接下来,我们有一个switch表达式,其中我们声明了一个名为t的新变量,并将i的类型存储在其中。

我们有两个case和一个default回退。前两个case检查i是否为bool,如果不是,则回退打印。Printf允许格式化输出,其中%T打印变量的类型。

Docker

运行Go应用程序的一个很好的方法是将它们打包成Docker镜像 ,使它们可以在不同系统上运行。我们将使用多阶段Dockerfile来高效地构建和执行我们的Go程序。

为什么使用多阶段Dockerfile?

多阶段构建有助于保持最终镜像的小巧和高效,通过将构建环境与运行时环境分开。

让我们编写Dockerfile

dockerfile 复制代码
# 构建GO二进制文件
FROM golang:1.24.1-alpine AS build
COPY ./main.go ./main.go
RUN go build -o /bin/output ./main.go

# 执行GO二进制文件
FROM scratch
COPY --from=build /bin/output /bin/output
CMD ["/bin/output"]

构建阶段(build)

我们从官方的golang:1.24.1-alpine镜像开始。我们将main.go复制到容器中(你可以重命名),并编译它到/bin/output

运行时阶段

运行时阶段使用FROM scratch,这意味着它没有基础操作系统。scratch是一个空镜像,其他任何东西都不存在。这减小了镜像的大小。我们使用命令COPY --from=build从构建阶段高效地复制编译后的二进制文件,并设置CMD["/bin/output"]作为入口命令。

构建和运行Docker镜像

要构建和运行镜像,请使用以下命令:

perl 复制代码
# 构建镜像(点表示当前目录作为上下文)
docker build -t my-go-app:latest .

# 运行容器
docker run my-go-app:latest

原文:dev.to/link2twenty...

相关推荐
梦想很大很大7 小时前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
lekami_兰12 小时前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
却尘15 小时前
一篇小白也能看懂的 Go 字符串拼接 & Builder & cap 全家桶
后端·go
ん贤16 小时前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁
mtngt111 天前
AI DDD重构实践
go
Grassto3 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto4 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室5 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题5 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo
啊汉7 天前
古文观芷App搜索方案深度解析:打造极致性能的古文搜索引擎
go·软件随想