学习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...

相关推荐
addaduvyhup2 小时前
从 Java 的 Spring Boot MVC 转向 Go 语言开发的差异变化
java·spring boot·go·mvc
<e^πi+1=0>3 小时前
playwright-go实战:自动化登录测试
go·playwright
X_PENG5 小时前
【golang】是否复用buffer?分级缓冲池实现&slice底层原理
go
forever2313 小时前
go分布式master,worker服务,配合consul实现服务自动发现
go
程序员爱钓鱼13 小时前
Go 语言实用工具:如何高效解压 ZIP 文件
前端·后端·go
孔令飞13 小时前
简单粗暴:如何写一篇高质量的技术文章?
人工智能·云原生·go
zhuyasen1 天前
高性能缓存:使用 Redis 和本地内存缓存实战示例
redis·缓存·go
洛卡卡了1 天前
Gin 框架学习实录 · 第6篇:构建通用响应模块(统一结构体 + 错误码 + 分页封装)
go
洛卡卡了1 天前
Gin 框架学习实录 · 第5篇:用户模块增删改查 + 分页查询接口
go
我是前端小学生2 天前
面试官:在go语言中,主协程如何等待其余协程完毕再操作?
go