package、import、func

  • package 关键字声明了代码所属的包。
  • Go 语言里所有的代码都被分为不同的包。
    • Go 提供了一个标准库,它由 math、compression、cryptography 等 package 组成,每个 package 都能做一类工作。
  • import 关键字指明了代码所需要使用的 package。每个 package 里面都包含很多函数(function)。
  • func 关键字声明了一个函数。
    • 函数体需要使用 { } 括起来,这样的话 Go 就知道 函数的开始和结束位置了

main

  • main 这个标识符很特殊:
    当你运行 Go 语言编写的程序时,会从 main package 的 main function 开始执行。
  • 没有 main,那么 Go 编译器就会报错,因为它不知道程序应该从哪开始。

fmt.Print 和 fmt.Println

  • 下面例子里使用了 Print,Println 函数。
  • 可以传递若干个参数,之间用逗号分开。
  • 参数可以是字符串、数字、数学表达式等等。
  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("My weight on the surface of Mars is", 149.0*0.3783, "lbs, and I would be", 41*365.2425/687, "years old.")
  5. }

格式化打印

  • 可以使用 Printf 来控制打印的输出结果。
  • 与 Print 和 Println 不同,Printf 的第一个参数必须是字符串。
    • 这个字符串里包含了像 %v 这样的格式化动词,它的值由第二个参数的值所代替。
    • 如果指定了多个格式化动词,那么它们的值由后边的参数值按其顺序进行替换
  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Printf("I'm %v years old\n", 8 * 2)
  5. fmt.Printf("my %v is %v lbs\n", "weight", 70 * 2)
  6. }

使用 Printf 对齐文本

  • 在格式化动词里指定宽度,就可以对齐文本。
    • 例如,%4v,就是向左填充到足够4个宽度
  • 正数,向左填充空格
  • 负数,向右填充空格
  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Printf("%-15v $%4v\n","SpaceX",94)
  5. fmt.Printf("%-15v $%4v\n","ve",111)
  6. }

rand

  • 使用 rand 包,可以生成伪随机数
    • 例如,Intn 可以返回一个指定范围的随机整数
  • import 的路径是 “math/rand”
  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. )
  6. func main() {
  7. var num = rand.Intn(10) + 1
  8. fmt.Println(num)
  9. num = rand.Intn(10) + 1
  10. fmt.Println(num)
  11. }

strings.Contains

  • 来自 strings 包的 Contains 函数可以判断某个字符串是否包含另外要给的字符串
  1. package main
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. func main() {
  7. fmt.Println("You find yourself in a dimly lit cavern.")
  8. var command = "walk outside"
  9. var exit = strings.Contains(command, "outside")
  10. fmt.Println("You leave the cave:", exit)
  11. }

使用 switch 做分支

  • switch 语句可以对字符串进行匹配
  • switch 语句也可以对数字进行匹配
  • 还有一个 fallthrough 关键字,它用来执行下一个 case 的 body 部分。这一点与 C#、Java 等语言不一样。
  1. package main
  2. import "fmt"
  3. func main() {
  4. var room = "lake"
  5. switch room {
  6. case "cave":
  7. fmt.Println("You find yourself in a dimly lit cavern.")
  8. case "lake":
  9. fmt.Println("The ice seems solid enough.")
  10. fallthrough
  11. case "underwater":
  12. fmt.Println("The water is freezing cold.")
  13. }
  14. }

使用循环做重复

  • for 关键字可以让你的代码重复执行
  • for 后边没有跟条件,那就是无限循环。
    • 可以使用 break 跳出循环
  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. var count = 10
  8. for count > 0 {
  9. fmt.Println(count)
  10. time.Sleep(time.Second)
  11. count--
  12. }
  13. fmt.Println("Liftoff!")
  14. }
  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. var count = 10
  8. for {
  9. if count <= 0 {
  10. break
  11. }
  12. fmt.Println(count)
  13. time.Sleep(time.Second)
  14. count--
  15. }
  16. fmt.Println("Liftoff!")
  17. }

变量的作用域

  • 当变量被声明以后,它就进入了作用域(变量就变得可见了)。
    • 只要变量在作用域内,你就可以访问它
    • 否则,访问它会报错的
  • 变量声明的位置,决定了它的作用域。
  • 作用域的好处?
    • 可以在不同的作用域内使用相同的变量名
  • 在 Go 里面,通常,作用域的范围就是 { } 之间的部分

A - 图1

  • count 变量就是在 function 作用域内
  • num 的作用域就是 for 的循环体

短声明

  • 在 Go 里,可以使用 var 来声明变量:
    • var count = 10
  • 但是也可以使用短声明:
    • count := 10
  • 这两种方式的效果是一样的
  • 不仅声明语句更短,而且可以在无法使用 var 的地方使用

使用 var 声明变量

A - 图2

使用短声明

A - 图3

在 if 语句里使用短声明来声明变量

A - 图4

在 switch 语句里使用短声明来声明变量

A - 图5

package 作用域

  • era 变量是在 main 函数外声明的
    • 它拥有 package 作用域
    • 如果 main package 有多个函数,那么 era 对它们都可见
  • 短声明不可用来声明 package 作用域的变量

A - 图6

练习:展示随机日期

  • 修改这个程序,让其能处理闰年的情况
    • 生成随机年份,而不是写死 2018
    • 二月份:闰年为 29 天,非闰年为 28 天
    • 使用 for 循环生成和展示 10 个日期

A - 图7

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. )
  6. var era = "AD"
  7. func main() {
  8. for count := 0; count < 10; count++ {
  9. year := 2022 + rand.Intn(10)
  10. leap := year%400 == 0 || (year%4 == 0 && year%100 != 0)
  11. month := rand.Intn(12) + 1
  12. daysInMonth := 31
  13. switch month {
  14. case 2:
  15. daysInMonth = 28
  16. if leap {
  17. daysInMonth = 29
  18. }
  19. case 4, 6, 9, 11:
  20. daysInMonth = 30
  21. }
  22. day := rand.Intn(daysInMonth) + 1
  23. fmt.Println(era, year, month, day)
  24. }
  25. }