一、命名
GO语言中的函数名、变量名、常量名、类型名、语句标号和下划线等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母或者下划线开头,后面可以接任意数量的字母、数字或者下划线。严格区分大小写字母。
Go语言中25个关键字;关键字不能用于自定义的名字,只能在特定的语法中使用
推荐使用驼峰式命名
二、声明
声明语句定义了程序的各种实体对象以及部分或全部的属性。Go语言主要有四种类型的声明语句:var
、const
、type
和func
,分别对应变量、常量、类型和函数实体对象的声明。
var a = 2
const b = 3
三、变量
3.1 变量的初始化
var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。变量声明的一般语法如下:
var 变量名 类型 = 表达式
其中“类型”或“= 表达式”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量。 数值类型变量对应的零值是0,布尔类型变量对应的零值是false,字符串类型对应的零值是空字符串,接口或引用类型(包括slice、map、chan和函数)变量对应的零值是nil。数组或结构体等聚合类型对应的零值是每个元素或字段都是对应该类型的零值。
零值初始化机制可以确保每个声明的变量总是有一个良好定义的值,因此在Go语言中不存在未初始化的变量。
3.2 短变量声明
在函数中,简洁赋值语句 := 可在类型明确的地方代替 var 声明。
常量不能用短变量声明
函数外的每个语句都必须以关键字开始(var, func 等等),因此 := 结构不能在函数外使用。
package main
import "fmt"
func main() {
var i, j int = 1, 2
k := 3
c, python, java := true, false, "no!"
fmt.Println(i, j, k, c, python, java)
}
PS:简短变量声明语句对这些已经声明过的变量就只有赋值行为了。
a, b := 1, 2 //声明
a, b := 3, 4 // 赋值
3.3 指针
一个指针的值是另一个变量的地址。通过指针,我们可以直接读或者更新对应变量的值。
var a = 1
// &a 就是a变量的内存地址
var p *int //创建一个整形指针
p = &a //
fmt.PrintIn(*p)
在go中,返回函数中局部变量的地址是安全的。如
var p = f()
func f() *int{
v := 1
return * v
}
3.4 new函数
我们可以通过new
函数创建变量。 。表达式new(T)将创建一个T类型的匿名变 量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为 *T 。
p := new(int) // p, *int 类型, 指向匿名的 int 变量
fmt.Println(*p) // "0"
*p = 2 // 设置 int 匿名变量的值为 2
fmt.Println(*p) // "2"
下面的两个new(int)
函数有着相同的行为:
func newInt() *int {
return new(int)
}
func newInt() *int {
var dummy int
return &dummy
}
3.5 变量的声明周期
3.6 赋值
使用赋值语句可以更新一个变量的值,最简单的赋值语句是将要被赋值的变量放在=的左边,新值的表达式放在=的右边。
数值变量可以通过使用自增和自减
3.6.1 元组赋值
var a = 1
var b = 2
a, b = b , a // a=2, b=1
3.7 type
在go中,可以通过type
关键字给类型名字取别名。
type zhengshu int
var a zhengshu
四、函数
函数是基本的代码块,用于执行一个任务。GO中最少有个main()函数。
4.1 函数的声明
定义格式如下:
func func_name(参数) result-list{
函数体
}
func add(a int, b int) int{
return a+b
}
函数声明包括函数名、形式参数列表、返回值列表(可省略)以及函数体。
每一次函数调用都必须按照声明顺序为所有参数提供实参(参数值)。在函数调用时,Go语 言没有默认参数值,也没有任何方法可以通过参数名指定形参,因此形参和返回值的变量名 对于函数调用者而言没有意义。
4.2 多值返回
在Go中,一个函数可以返回多个值。
func calculate(a, b int) (int, int){
return a+b, a-b
}
m, n = calculate(1,2)
调用多返回值函数时,返回给调用者的是一组值,调用者必须显式的将这些值分配给变量。
如果一个函数将所有的返回值都显示的变量名,那么该函数的return
语句可以省略操作数。这 称之为bare return
。base return
可以减少代码的重复,但是使得代码难以被理解。
func calculate(a,b int)(m int , n int){
m = a+b;
n = a-b;
return
}
4.3 递归
func fib(n int) int{
if(n == 1 || n ==2){
return 1
}
return fib(n-1) + fib(n-2)
}
大部分的编程语言使用固定大小的函数调用栈。固定大小栈会限制递归的深度,当你使用递归函数处理大量的数据时,需要避免栈溢出。但Go语言使用可变栈,栈的大小按需增加(初始时很小)。这使得GO使用递归不用考虑溢出和安全问题。
4.4 函数值
在Go中,函数被看作第一类值(first-class values):函数像其他值一样,拥有类型,可以被 赋值给其他变量,传递给函数,从函数返回。对函数值(function value)的调用类似函数调 用。例子如下:
func square(n int) int { return n * n }
func negative(n int) int { return -n }
func product(m, n int) int { return m * n }
f := square
fmt.Println(f(3)) // "9"
f = negative
fmt.Println(f(3)) // "-3"
fmt.Printf("%T
", f) // "func(int) int"
f = product // compile error: can't assign func(int, int) int to func(int) int
函数类型的零值是nil。调用值为nil的函数值会引起panic错误:
var f func(int) int
f(3)// 此处f的值为nil,会引起panic错误
var f func(int) int // 函数值可以和nil比较
if f != nil {
f(3)
}
但是函数值之间是不可比较的,也不能用函数值作为map的key。