前面简单说过有关Go语言的基础语法及其数据类型,大体上了解了Go语言程序的组成,而本文将讲述近乎全部编程语言都涉及的变量、常量以及运算符相关内容。算法
对该专业名词解释:计算机语言中能储存计算结果或能表示值抽象概念。变量能够经过变量名访问。Go语言中的变量由字母、数字、下划线组成,首字母不能够为数字。耳熟能详了哈~shell
笔者的理解:我编写程序的时候须要使用一个值,而且我一直想要重复使用,并且有时候这个值会发生变化等等,因此我须要声明一个变量来被这个值赋之。编程
变量声明通常格式:数组
var 变量名 变量类型
var:变量声明关键字,表示声明变量编程语言
其次是变量的名字,最后是变量的类型(如int)ide
固然也有其余的变化格式,咱们直接看实例:函数
package main var a1 int = 10 var a2 = "hello world" var b1 = 11 var b2 string = "你好,世界" //c1 := 12 //这种不带声明格式的只能在函数体中出现,不然会报错:non-declaration statement outside function body var c2 bool func main(){ println(a1,a2,b1,b2,c2) c1 := 12 //这种变量声明要注意:c1变量没有被提早声明过才能够这样赋值 println(c1) }
运行结果:指针
10 hello world 11 你好,世界 false
12code
固然变量也能够一块儿声明,程序执行时会自动推断变量类型(与Python相像)blog
package main //写法一: var v1, v2, v3 int //写法二: var v11, v22, v33 = 4, 5, "hello" //写法三:(需写在全局变量中,不能够写在函数体内部) var ( vv1 int vv2 bool = true ) func main(){ v1, v2, v3 = 1, 2, 3 println(v1,v2,v3) println(v11,v22,v33) println(vv1,vv2) }
运行结果:
1 2 3
4 5 hello
0 true
在变量的初始化时省略变量的类型而由系统自动推断,声明语句写上 var 关键字实际上是显得有些多余了,所以咱们能够将它们简写为 a := 50 或 b := false。 编译器对此会自动推断a为int类型,b为bool类型。
这种简短形式的变量声明须要注意如下事项:
另外,变量须要先声明后使用(全部方式都同样);当声明了局部变量(函数体内部),而未使用,也会编译出错;可是全局变量能够不使用。
int、float、bool、string这些基本类型都属于值类型。值类型的典型特征就是:咱们所赋值的操做在计算机中存储和使用的过程是这样的(先作了解便可):
定义变量到内存中,值类型的变量存储在栈中,赋值,是将该值进行了一个拷贝再将这个拷贝的内容赋予给变量,变量(值类型)与拷贝的值之间的关系:变量直接指向内存中的值。
能够经过&变量名获取变量的内存地址,每次获取的地址可能不同。
package main var a int = 10 func main(){ println(a) println(&a) }
运行结果:
10
0x4a4018
Go语言中的引用类型有:映射(map)、数组切片(slice)、通道(channel)、方法和函数。
Go语言存在垃圾回收器,所以在一个本地变量再也不被使用时就会被回收掉,此时本地变量的生命周期由它们的做用域决定。对于管理本地变量的生命周期,咱们须要用到指针,使用指针就可使得对应变量的生命周期独立与做用域。
使用指针能控制变量的生命周期,不受做用域的影响,另外变量在传递过程当中使成本最小化,而且能够修改变量的内容,而不是对复制的值进行操做。固然,指针也是一个变量,表示的是存放(保存了)另外一个变量的内存地址,任何被指针保存的内存地址的变量均可以经过指针来修改内容。
package main import "fmt" func main(){ a := 3 p := &a //获取变量a的内存地址,而且将其赋值给p fmt.Printf("a的值为: %v,a的指针为: %v,p指向的变量的值为: %v\n",a,p,*p) }
运行结果:
~~~a的值为: 3,a的指针为: 0xc4200160d8,p指向的变量的值为: 3
也就是说*p和a的值是相等的,能够交换使用。二者都与同一块内存地址相关联,任意一个变量进行修改操做都会影响到另外一个变量的值,可是若变量p被赋值其余变量的指针就不行了 ### 空指针 当一个指针被定义后没有分配到任何变量,值就为nil,叫作空指针。nil在概念上和其它语言的null、None、nil、NULL同样,都指代零值或空值。 #### 实例1.5——空指针 ~~~go package main import "fmt" func main() { var ptr *int fmt.Printf("ptr 的值为 : %x\n", ptr ) }
~~~运行结果:ptr 的值为 : 0
# 2、常量 Go语言常量就是值的标识符,程序运行时,不会被修改。常量中的数据类型只能够是bool型、数字型和字符串型。 常量定义格式: ~~~go const identifier [type] = value
解释:const ——关键字 ,表示该变量将定义为常量不可更改
package main import "fmt" const m string = "hello" //显式类型定义 const n = "world" //隐式类型定义 func main() { const LENGTH int = 10 const WIDTH int = 5 var area int const a, b, c = 1, false, "str" //多重赋值 area = LENGTH * WIDTH fmt.Printf("面积为 : %d\n", area) println(m, n) println(a, b, c) //m = "wrong" //错误示范 //println(m) //编译报错:cannot assign to m,说明const变量不能够更改 }
运行结果:
面积为 : 50 hello world 1 false str
固然,常量也可用做枚举
const ( Yes = 0 No = 1 Notsure = 2 )
iota,一个特殊常量,能够认为是一个可以被编译器修改的常量
package main import "fmt" func main() { const ( a = iota //0 b //1 c //2 d = "ha" //独立值,iota += 1 e //"ha" iota += 1 f = 100 //iota +=1 g //100 iota +=1 h = iota //7,恢复计数 i //8 ) fmt.Println(a,b,c,d,e,f,g,h,i) }
运行结果
~~~0 1 2 ha ha 100 100 7 8
从给出结果的现象能够知道: 一、在go语言编程中,iota是一个会在程序运行过程当中自动变换的常量; 二、在给const修饰的变量赋值时,每次会隐藏性自增1,不管是否是在赋予给定的值; 三、当赋予给定的值给变量后,该变量以后的变量又未赋予其余的给定的值时,其后面的变量的值和该变量相等;就如上面的d和e,f和g ;可是有例外(看下面的例子) 四、而当变量回归赋值iota时,将按照自增的结果赋值给变量。 以下面的例子: #### 实例2.3——有趣的iota ~~~go package main import "fmt" const ( i=1<<iota //"<<"——此符号表示的位运算符,左移;此时对应关系为i——>1<<iota:1左移0位;则i的值为1 j=3<<iota //此时对应关系为:j——>3<<iota为3,iota的值为1,则左移1位,即0011——>0110=6 k //可是此时关系为k——>3<<iota,而不是6<<2,iota为2,k的值为12 l m=iota ) func main() { fmt.Println("i=",i) fmt.Println("j=",j) fmt.Println("k=",k) fmt.Println("l=",l) fmt.Println("m=",m) }
运行结果:
i= 1 j= 6 k= 12 l= 24 m= 4
近乎全部的程序语言都有运算符,运算符的做用无外乎两个:数学运算和逻辑运算
Go语言内置的运算符有:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其余运算符
包括:+、-、*、/、%、++、-- 后三个表示取余,自增,自减
package main import "fmt" func main() { var a int = 21 var b int = 10 var c int c = a + b fmt.Printf("加法: c 的值为 %d\n", c ) c = a - b fmt.Printf("减法: c 的值为 %d\n", c ) c = a * b fmt.Printf("乘法: c 的值为 %d\n", c ) c = a / b fmt.Printf("除法: c 的值为 %d\n", c ) c = a % b fmt.Printf("取余: c 的值为 %d\n", c ) a++ fmt.Printf("a自增: 值为 %d\n", a ) a-- fmt.Printf("a自减: 值为 %d\n", a ) }
运行结果:
加法: c 的值为 31 减法: c 的值为 11 乘法: c 的值为 210 除法: c 的值为 2 取余: c 的值为 1 a自增: 值为 22 a自减: 值为 21
包括 == 、!=、>、<、 >=、 <= 分别对应:判断是否等于,是否不等于,大于,小于,大于等于,小于等于
本文对此不作代码演示了,由于涉及到控制流程语句下一篇会讲
下图表列出了全部Go语言的逻辑运算符。假定 A 值为 True,B 值为 False。
位运算符的做用是对整数在内存中的二进制位进行操做。
下表列出了位运算符 &, |, 和 ^ 的计算:表示逻辑上的“与或非”的关系
总结:
&:两边为真才为真
|:两边为假才为假
^:两边不一样才为真
固然还有上述的左移、右移计算。举例说明:
60&13的结果为:12,计算方法是60和13转换为二进制作按位与运算,即:0011 1100 & 0000 1101= 0000 1100
60|13的结果为:61,计算方法是60和13转换为二进制作按位或运算,即:0011 1100 | 0000 1101= 0011 1101
赋值运算符以下:
主要就是上面所提到的&和*,分别表示为返回变量存储地址和指针变量
有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了全部运算符以及它们的优先级,由上至下表明优先级由高到低:(推荐编程的时候使用括号提高优先级,也是为了加强代码的可读性)
本文讲述了go语言中有关变量、常量、运算符的内容。变量中注意定义变量的格式与位置,尤为是简明格式,其次是常量,须要留意一个特殊常量iota。最后则是运算符,须要在实际编程的案例中使用才能体会感悟。