常量与变量
常量
- 用const定义,用来存储不可改变的数据
const pname [type]=value
可以省略type,,因为可以根据值来推测其类型- const c2=自定义函数()会报错,因为在编译期间自定义函数属于未知,无法用于常量的赋值,但内置函数可以使用
- 常量也允许并行赋值的形式
const beef, two, c = "eat", 2, "veg"
- 常量在go中是弱类型
如何体现:
1. 给int起个别名 sint
2. 如果函数形参为sint 而传参为int,编译期会出错误,反之一样
3. 而当传参为常量时,不会出错,因为弱类型,在实际用到时才确定具体类型
package main
type sint int
func main() {
test(1) // 传参为常量时 正确
//test(int(1)) // 传参为int时 错误
}
func test(a sint) {
print("测试成功")
}
iota的用法
- 可以用作自增长常量,用来做枚举
const(
a = 0
b = 1
c = 2
)
//通过iota可以简化为
const(
a = iota
b = iota
c = iota
)
//继续简化
const(
a = iota
b
c
)
变量
变量采用 var name type 格式的原因:
避免像C语言一样有含糊不清的声明形式
例如:在C语言中 int* a,b中 a为指针,b不是
var a, b *int 轻松的将他们声明为指针类型
从左到右顺序阅读,更加容易阅读
- 当一个变量被声明之后,系统自动赋予他该类型的零值(声明后直接初始化)
func main() {
var a int
print(a) // 输出 0
}
- 如果一个变量在函数体外声明,则可被其他文件使用
- go语言可以根据变量的值自动推断其类型,而且是在编译时已经完成了推断(python这种动态语言是在运行时进行推断)
- 在函数体内声明局部变量时,应使用简短声明语句 :=
a := 1
值类型和引用类型
在golang中只有三种引用类型 切片slice,字典map,管道channel(底层用的都是指针),其余全是值类型
引用数据可以简单理解为指针类型,他们都是通过make进行初始化
a :=[5]int{2,3,4,5,6}
b := a
b[2]=77
fmt.Println(a, b)
这种的b改变但是a不改变,因为是值传递
a :=[]int{2,3,4,5,6}
b := a
b[2]=77
fmt.Println(a, b)
这种的a和b全部改变,因为用的切片本质是地址传递
打印输出
- %s字符串标识符
%..
任意类型标识符- %v相应值的默认格式
:=赋值操作符
a:=40 相当于加上var 所以 声明过的变量再用:=
会报错,应该用=
改变值的内容
在go中想要抛弃变量的值可以简单使用 a,b=b,a
/*
m函数中对a相当于一个局部变量(重新声明的)
*/
package main
var a = "G"
func main() {
n()
m()
n()
}
func n() { print(a) }
func m() {
a := "O"
print(a)
}
/*
m中相当于给全局变量a重新赋值
*/
package main
var a = "G"
func main() {
n()
m()
n()
}
func n() { print(a) }
func m() {
a = "O"
print(a)
}
/*
f2中调用的值还是全局变量,很正常,f1中声明的变量对f2中不可见
*/
package main
var a string
func main() {
a = "G"
print(a)
f1()
}
func f1() {
a := "O"
print(a)
f2()
}
func f2() {
print(a)
}
init函数
- 不会被人为调用,而是在每个包完成初始化时后自动执行(执行优先级比main函数高)
- 每个源文件只能包含一个init函数,并且按照包的依赖关系顺序执行