go语言基础语法(下)|青训营

51 阅读6分钟

四、Go 语言变量 变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念,变量可以通过变量名访问

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字

  1. 变量声明 声明变量的一般形式是使用 var 关键字 var identifier type

//可以一次声明多个变量: var identifier1, identifier2 type

实例 package main

import "fmt"

func main() { var a string = "hello" fmt.Println(a)

var b, c int = 1, 2
fmt.Println(b, c)

}

//输出结果如下 hello 1 2

2.变量声明方法 第一种,指定变量类型,如果没有初始化,则变量默认为零值

var v_name v_type v_name = value

package main

import "fmt"

func main() { //声明一个变量并初始化 var a = "goroute" fmt.Println(a)

//没有初始化就为零
var b int
fmt.Println(b)

//布尔值零值为false
var c bool
fmt.Println(c)

}

//输出的结果如下 goroute 0 false

数值类型(包括complex64/128)为 0

布尔类型为 false

字符串为 ""(空字符串)

第二种,根据值自行判定变量类型

var v_name = value

package main

import "fmt"

func main() { var a = true fmt.Println(a) }

//输出结果如下 true

第三种,如果变量已经使用 var 声明过了,再使用 := 声明变量,就产生编译错误

package main

import "fmt"

func main() { a := 1 fmt.Println(a) }

//此时不会产生编译错误,因为有声明新的变量,因为 := 是一个声明语句

a := 1 相等于: var a int a =1 1 2 可以将 var a string = “hello” 简写为 a := “hello” package main

import "fmt"

func main() { //相当于var a string = "hello" a := "hello" fmt.Println(a) }

  1. 多变量声明 类型相同多个变量, 非全局变量 package main

import "fmt"

func main() { a, b, c := 1, 2, 3 fmt.Println(a, b, c) }

因式分解法 // 这种因式分解关键字的写法一般用于声明全局变量

var( test1 int test2 float32 test3 string )

实例 package main

import "fmt"

var x, y int

var ( a int b bool )

var c, d int = 1, 2

var e, f = 666, "hello world!"

func main() { //这种不带声明格式的只能在函数体中出现 g, h := 7878, "happy" fmt.Println(x, y, a, b, c, d, e, f, g, h) }

//输出结果如下 0 0 0 false 1 2 666 hello world! 7878 happy

  1. 值类型和引用类型 所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值:

当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝:

可以通过 &i 来获取变量 i 的内存地址,例如:0xf840000040(每次的地址都可能不一样)

值类型变量的值存储在堆中

内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同

更复杂的数据通常会需要使用多个字,这些数据一般使用引用类型保存

一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。

这个内存地址称之为指针,这个指针实际上也被存在另外的某一个值中

同一个引用类型的指针指向的多个字可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址。

当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。

如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2 也会受到影响。

4.1 内存的压栈 压栈的顺序:先进后出

函数加入栈后,会执行赋值

弹栈:变量的释放

4.2 内存的堆 堆的顺序:先进先出

4.3 示例 package main

import "fmt"

//变量在内存中的存储方式

var num int = 10 var sun int = 20

func main() {

var test1 = "hello"
var test2 = "world"

fmt.Println("num=", num)
//调用内存地址使用&
fmt.Println("num的内存地址是", &num)
fmt.Println("sun的内存地址是", &sun)
//调用函数中中变量
fmt.Println(test1)
fmt.Println(test2)

}

//输出结果如下 num= 10 num的内存地址是 0x709258 sun的内存地址是 0x709260 hello world

上面代码中,在全局定义的变量是存放在栈中的,他是属于文件的

var num int = 10 var sun int = 20

而局部变量则是存放在堆中,是属于main函数的

var test1 = "hello"
var test2 = "world"

当全局变量加载完以后会加载main函数,但是main函数中定义的变量并不会被压栈,而是会被放入堆中

在test函数中是无法调用main函数中的变量的,存放位置是不同的

函数中的变量会随着函数的结束而结束它的生命周期

  1. 变量的作用域 在函数内部声明的变量教局部变量,生命周期仅限于函数内部

在函数外部声明的变量交全局变量,生命周期作用于整个包,如果是大写首字母,则作用域整个程序

语句块中的变量,生命周期仅限于语句块,语句块外部不能被识别

示例

package main

import "fmt"

//定义全局变量 var a string = "10"

func main() { n() m()

fmt.Println("主函数输出:", a)

}

func n() { println("n函数输出:", a) }

func m() { a := "0" fmt.Println("m的函数输出:", a) }

//输出结果如下 n函数输出: 10 m的函数输出: 0 主函数输出: 10

  1. 简短形式,使用 := 赋值操作符 查看变量的数据类型 package main

import "fmt"

/* := 定义即声明,无需写var,系统会自动推断数据类型,无需自定义数据类型 格式只能在函数体内 */

func main() { num := "hello" fmt.Println(num) //查看变量的数据类型 fmt.Printf("num的数据类型是:%T", num) }

//输出结果为 hello num的数据类型是:string

  1. 空白标识符 空白标识符_ 也被用于抛弃值,如值5在_,b=5,7中被抛弃

_实际上是一个只写变量,你不能得到它的值,这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你不需要从一个函数得到所有返回值

并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和 错误 err 是通过调用Func1 函数同时得到:val,err = Func(var1)

package main

import "fmt"

func main() { _, numb, strs := numbers() //只获取函数返回值的后两个 fmt.Println(numb, strs) }

func numbers() (int, int, string) { a, b, c := 1, 2, "str" return a, b, c }

//输出结果如下 2 str

五、常量

  1. 什么是常量 常量是一个简单值的标识符,使用 const 修饰,是程序在运行时,不会被修改的量

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量的定义格式:

const identifier [type] = value

//可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型

//显式类型定义: const b string = "abc"

//隐式类型定义: const b = "abc"

//多个相同类型的声明可以简写为: const c_name1, c_name2 = value1, value2