程序结构

123 阅读4分钟

go语言的 hello world 的写法为:

package main  
  
import "fmt"  
  
func main() {  
	fmt.Println("Hello, World!")  
}

需要注意:左大括号不能另起一行,否则会报错。

声明包: package

go程序都是由包构成,每个项目都是从 main 包开始运行,package 表示当前在main包中。

导入包:import

在go语言中,使用 import 导入包,在上述例子中,导入了 fmt 包,并使用了 fmt 包中的 Println() 函数来输出 "hello world" 。

当需要导入多个包的时候有两种方式:

import "fmt"
import "math"
import(
	"fmt"
	"math"
)

变量声明

go语言中声明变量的模板为:

var 变量名 类型 = 表达式

在声明中,类型和表达式两者可省去一个。

  • 当省去的为类型的时候,则会按照表达式自动判断变量的类型。
  • 当省去表达式的时候,则会自动给该变量初始化为零

可以多个变量一起初始化:

var a,b,c int  // int int int

也可以分别赋值:

var x,y,z = true,2.3,"four" //bool flot64 string

也可以将变量赋值为函数返回的参数:

var f,err = os.Open(name) //Open函数返回两个参数

当函数返回两个值,但是你只需要一个值的时候,可以使用 _ 丢弃不需要的值:

var f,_ = os.Open(name)

此时只接收了 Open 函数的第一个值。

函数中声明变量

在函数中,有一种简洁的方式声明变量,但是这种声明方式不能再函数外面使用。

可以使用 := 来代替 var 声明 模板为:

变量名 := 表达式

例如,在函数中可以这样写:

f,err := os.Open(name)

赋值

go语言的赋值与c基本差不多,但是在go语言中有一个创新的地方是新增了一个元组赋值,它允许同时更新多个变量的值。在赋值之前,赋值语句右边的所有表达式将会先进行求值,然后再统一更新左边对应变量的值。

例如:

x,y = y,x //交换x,y的值
i,j,k = 1,2,3 

但如果表达式太复杂的话,应该尽量避免过度使用元组赋值;因为每个变量单独赋值语句的写法可读性会更好。

运算符

![[Pasted image 20230724095303.png]]

输出函数

可以使用 println 来打印多个变量:

type point struct{
	x ,y int
}

a := "123"
p := point{1,2}

fmt.Println(a, p) //123 {1,2}

printf 和 c 语言的printf 类似,可以使用格式控制符,在 go 语言中,可以使用 %v 来自动识别数据类型:

a := "123"
p := point{1,2}

fmt.Printf("a=%v",a)
fmt.Println()
fmt.Printf("p=%v",p)
fmt.Println()
fmt.Printf("p=%+v",p)
fmt.Println()
fmt.Printf("p=%#v",p)

/*
a=123
p={1 2}
p={x:1 y:2}
p=main.point{x:1, y:2}
*/

流程控制

if...else...

if 语句的条件表达式必须是布尔类型的,可以省略小括号,并且左边的大括号不能另起一行。

package main
import "fmt"

func main(){
    x := 5
    if(x==5){  //括号要或者不要都行
        fmt.Println("ihis")
    }
}

此外,在 if 语句中,还支持初始化语句,能够初始化一个或者多个局部变量,有效范围为整个 if 语句。

package main
import "fmt"

func main(){
    
    if x:= 5; (x==5) {
        fmt.Println("ihis")
    }
}

同样的,小括号打或者不打都可以。在这个代码中,将 x:=5 初始化语句放到了 if 语句当中。但是只能放一个表达式

switch

每一个 case 块后面不需要显示的执行 break 语句,程序不会自动执行下一个语句,但是如果想执行下一个语句,就可以在 case 块的结尾处执行 fallthrough,如果需要阻止 fallthrough ,就可以显示的执行 break。

package main
import "fmt"

func main() {
  a, b, c, x := 2, 3, 4, 2
  switch x {
  case a, b:
    fmt.Println("x == a || x == b")
    fallthrough
  case c:
    fmt.Println("x == c")
  case 3:
    fmt.Println("x == 3")
  default:
    fmt.Println("x 不符合任何 case 条件")
  }
} 

//x == a || x == b
//x == c

另外,switch 同样支持初始化语句,在 case 块中也支持条件判断:

package main
import "fmt"

func main() {
  switch y := 5; {
  case y > 5:
    fmt.Println("y > 5")
  case y > 0 && y <= 5:
    fmt.Println("y > 0 && y <= 5")
  default:
    fmt.Println("y = ", y)
  }
}
// y > 0 && y <= 5

但是需要注意,相邻之间的 case 不构成多条件匹配,还有不能出现重复的 case 常量值。

for

go语言中只有一个循环语句就是 for 循环语句。

用法和其他语言类似:

package main
import "fmt"

func main() {
  for i := 0; i < 5; i++ {
    fmt.Println("i = ", i)
  }
}

在 for 循环中没有小括号。

使用 for 循环模拟 while

package main
import "fmt"

func main() {
  j := 0
  for j < 5 {
    j++
    fmt.Println("j = ", j)
  }
}
// 模拟 while(条件表达式)

package main
import "fmt"

func main() {
  var k int
  for {
    k++
    if k == 2 {
      continue
    }
    if k > 5 {
      break
    }
    fmt.Println("k = ", k)
  }
}
//模拟 while(true)

for 循环还有一个 for range 遍历,类似于c++中的 for(auto : v) ,它支持遍历的数据类型有字符串、数组、数组指针、slice、map、channel,返回索引、键值数据

对于 range 遍历数数组的时候,它会有两个返回值,第一个是索引,第二个是对应位置的值。

下面举例遍历一个字符串:

package main
import "fmt"

func main() {
  str := "hello"
  for _ , char := range str {
    fmt.Println(string(char))
  }
}

golang的字符称为 rune ,等价于C中的 char ,可直接与整数转换,但是 rune 实际是整型,必需先将其转换为 string 才能打印出来,否则打印出来的是一个整数