Go 语言入门指南:基础语法和常用特性解析 | 青训营

66 阅读4分钟

变量声明

方式一:使用var关键字

// 声明变量,默认值为0
var a int
// 声明变量,并初始化值
var b int = 100
// 变量初始化时可省去数据类型,系统会通过值自动匹配变量的数据类型
var c =100   

// 声明多个变量
var a, b, c int = 1, 2, 3
var (
    a int =8
    b *int32
    c int64 = 32
    d string = "hello"
    t bool = true
)

方式二:使用":="声明并赋值

n1 := 5
n2 := (int64)8
s1 := "hello"

注:":="不能用于声明全局变量

常量声明

使用const关键字

const NUM = 10
const PI = 3.14159

NUM = 101 // 错误,常量不允许被修改


const (
    SPRING = 0
    SUMMER = 1
    AUTUMN = 2
    WINTER = 3
)

// 可以在const()中使用iota关键字,每行的iota会自动累加1,第一行的iota默认为0
const (
    SPRING = 2*iota  // SPRING = 2 * 0 = 0
    SUMMER           // SUMMER = 2 * 1 = 2
    AUTUMN           // AUTUMN = 2 * 2 = 4
    WINTER           // WINTER = 2 * 3 = 6
)

数组

在go语言中,数组的长度是固定的,且由相同数据类型的元素组成。其在声明时需要指定长度大小,如

var arr1 [5]int          // 声明一个长度为5的整形数组,且默认值为0,即[0,0,0,0,0]

arr2 := [4]int{1,2,3,4}  // 声明一个长度为4的整型数组,且值为[1,2,3,4]

arr3 := [4]int{1,2}      // 声明一个长度为4的整型数组,且前两个元素的值分别为1,2,后两个元素的值默认为0,即[1,2,0,0]

注:在进行参数传递时,数组采用的是值拷贝的方式,另外,arr1与arr2的数据类型是不同的,arr1是[5]int类型,arr2是[4]int类型,因此在进行参数传递时会受到类型的限制,不够灵活。比如,如果函数的形参是[5]int类型,那么该形参只接收长度为5的整形数组。

切片

在go语言中,切片(slice)即动态数组,其在声明时不需要指定具体长度。切片是引用类型,内部结构包含地址,长度和容量。

var a []int              // 声明一个整形切片,由于还未初始化(未分配内存空间),a==nil
var a = []int{}          // 声明并初始化一个内容为空的整形切片,a!=nil

b := []int{1,2,3}        // 声明并初始化一个整形切片

c := make([]int, 2)      // 声明并初始化一个长度为2的切片
fmt.Println(c)           // [0,0]

d := make([]int, 2, 10)  // 声明并初始化一个长度为2,容量为10的切片
fmt.Println(d)           // [0,0]

注:在进行参数传递时,切片采用的是引用传递的方式。另外,a,b,c,d的数据类型相同,都是[]int。因此,如果函数的形参是[]int类型,那么该形参可以接收任意长度的整形切片。

映射

在go语言中,映射(map)是一种无序的键值对(key-value)集合,map同样是引用类型。

var map1 map[int]string  // 声明一个key是int类型,value是string类型的map,map1=nil
// 使用make为map1分配可以存储10组K-V对的内存空间
map1 = make(map[int]string,10)
map1[0] = "go"
map1[1] = "java"
fmt.println(map1)        // [0:go 1:java]


map2 := make(map[string]string) // 为map2分配内存空间
map2["one"] = "go"
map2["two"] = "java"
fmt.pritln(map2)         // [one:go two:java]
var map1 map[int]string  
map1[0] = "go"           // 报错

结构体

在go语言中,结构体是一种自定义数据类型,可以包含多个不同类型的字段。结构体是值类型。

// 定义结构体
type person struct {
    name string
    age  int
    hobby string
}

// 声明结构体
var p1 person
// 实例化结构体
p1.name = "john"
p1.age = 10
p1.hobby = "runing"


// 使用new关键字对结构体进行实例化,返回的是结构体类型指针
var p2 = new(person)
// 修改p2字段的值
(*p2).name = "amy"
(*p2).age = 22
(*p2).hobby = "reading"

// 实例化一个结构体
p3 := person{ name: "小王子", age: 18, hobby: "唱歌"}

// 实例化一个结构体,p4是指向该结构体的指针
p4 := &person{ name: "李华", age: 17, hobby: "runing"}

注:由于结构体是值类型,所以传参时采用的是值拷贝的方式,如果想要修改结构体字段的值,可以传入结构体指针类型的变量。

函数

函数是基本的代码块,用于执行一个任务。

func name( [parameter list] ) [return_types] {
    函数体 
}

Go语言中使用func关键字声明一个函数。name是函数名。parameter list是参数列表,return types是返回类型,当有多个返回值时,return types要使用()括起来。比如,

func test(a int) (int, bool) {
    a = a * 3 + 5
    if a % 2 == 0 {
        return a, true
    }
    return a, false
}

test函数接收一个int类型参数a作为输入,函数的返回值有两个,分别是int类型和bool类型。调用该函数时,可以用两个变量接收函数的输出,也可以使用_忽略函数的返回值。比如,

result, b := test(3)
result, _ := test(4)

此外,Go函数的返回值可以被命名,最后可以由return隐式返回,比如,

func add(a int,b int) (z int) {
    z = a + b
    return
}