变量声明
方式1
声明变量的一般形式是使用 var 关键字:
var name type
指定变量类型,声明后若不赋值,则使用默认值
var v_name v_type
v_name = value
方式2
根据值自行判定变量类型。
var v_name = value
方式3
省略var, 注意 :=左侧的变量不能是已经声明过的,否则会导致编译错误。
//短变量声明。只能在函数体使用
c := 10
另外,go语言变量如果只是声明而不使用,编译也会报错
多变量声明
类型相同的多个变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
//自动类型推断
var vname1, vname2, vname3 = v1, v2, v3
vname1, vname2, vname3 := v1, v2, v3
类型不同多个变量
//既可以声明局部变量,也可以声明全局变量
var (
var name1 int8
var flags bool
)
//这种方式目前只能在函数体中使用
name1, flag1 := "zhangsan", true
一个实例
package main
import ("fmt")
func main() {
var (
name = "zhangsan"
age = 18
)
var flags = true
if flags {
fmt.Println(name)
fmt.Println(age)
}
}
值类型
所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值
当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝
你可以通过 &name来获取变量 name的内存地址
package main
import ("fmt")
func main() {
var (
name = "zhangsan"
age = 18
)
fmt.Println(name)
fmt.Println(age)
fmt.Print("name变量地址:" )
fmt.Print(&name)
}
引用类型
一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。这个内存地址为称之为指针,这个指针实际上也被存在另外的某一个字中。
当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。
注意
如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a。
空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。
_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。
package main
import "fmt"
func main() {
//只需要返回部分值 _ 用来接收不需要的值
_, age := people()
fmt.Println(age)
}
func people()(string, int) {
return "zhangsan", 18
}
在同一个作用域里面,不能重复声明同名变量(声明变量相当于申请内存空间给变量)
_ 可以重复声明使用。
常量声明
const声明常量
//常量在定义时必须赋值
//它在程序运行期间是不可变的
const identifier [type] = value
多个相同类型的声明可以简写为:
const c_name1, c_name2 = value1, value2
用作枚举:
const (
Unknown = 0
Female = 1
Male = 2
)
常量可以用len(), cap(), unsafe.Sizeof()常量计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:
package main
import (
"fmt"
"unsafe"
)
const (
name = "wangwu"
nameLength = len(name)
c = unsafe.Sizeof(nameLength)
)
func main() {
fmt.Println(c)
fmt.Println(nameLength)
}
iota 特殊常量(常量计数器、枚举)
iota,特殊常量,可以认为是一个可以被编译器修改的常量。
在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每新增一行声明,iota增加1
iota 可以被用作枚举值:
const (
a = iota
b = iota
c = iota
)
第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:
const (
a = iota
//简写,相当于b = iota
b
c
)
package main
import (
"fmt"
)
const (
//a = 0
a = iota
b
c
d = 100
//相当于 e = 100
e
f
//重新开始计数
g = iota
)
func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
fmt.Println(f)
fmt.Println(g)
}
定义数量级 (这里的<<表示左移操作,1<<10表示将1的二进制表示向左移10位,也就是由1变成了10000000000,也就是十进制的1024。同理2<<2表示将2的二进制表示向左移2位,也就是由10变成了1000,也就是十进制的8。)
const (
_ = iota
KB = 1 << (10 * iota)
MB = 1 << (10 * iota)
GB = 1 << (10 * iota)
TB = 1 << (10 * iota)
PB = 1 << (10 * iota)
)
多个iota定义在一行
const (
a, b = iota + 1, iota + 2 //1,2
c, d //2,3
e, f //3,4
)
Go语言运算符
Go 语言内置的运算符有:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 其他运算符
算数运算符
+ 相加
- 相减
* 相乘
/ 相除
% 取余
++ 自增
-- 自减
关系运算符
== 等于
!= 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
逻辑运算符
&& 逻辑与
|| 逻辑或
! 逻辑非
位运算符
位运算符对整数在内存中的二进制位进行操作。
下表列出了位运算符 &, |, 和 ^ 的计算:
| p | q | p & q | p | q | p ^ q |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 1 | 1 |
<< 左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。
**>>**右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。
赋值运算符
赋值运算符
下表列出了所有Go语言的赋值运算符。
| 运算符 | 描述 | 实例 |
|---|---|---|
| = | 简单的赋值运算符,将一个表达式的值赋给一个左值 | C = A + B 将 A + B 表达式结果赋值给 C |
| += | 相加后再赋值 | C += A 等于 C = C + A |
| -= | 相减后再赋值 | C -= A 等于 C = C - A |
| *= | 相乘后再赋值 | C *= A 等于 C = C * A |
| /= | 相除后再赋值 | C /= A 等于 C = C / A |
| %= | 求余后再赋值 | C %= A 等于 C = C % A |
| <<= | 左移后赋值 | C <<= 2 等于 C = C << 2 |
| >>= | 右移后赋值 | C >>= 2 等于 C = C >> 2 |
| &= | 按位与后赋值 | C &= 2 等于 C = C & 2 |
| ^= | 按位异或后赋值 | C ^= 2 等于 C = C ^ 2 |
| |= | 按位或后赋值 | C |= 2 等于 C = C | 2 |
其他运算符
下表列出了Go语言的其他运算符。
| 运算符 | 描述 | 实例 |
|---|---|---|
| & | 返回变量存储地址 | &a; 将给出变量的实际地址。 |
| * | 指针变量。 | *a; 是一个指针变量 |
运算符优先级
| 优先级 | 运算符 |
|---|---|
| 7 | ^ ! |
| 6 | * / % <> & &^ |
| 5 | + - | ^ |
| 4 | == != < = > |
| 3 | <- |
| 2 | && |
| 1 | || |
除此之外,你可以用()将对应表达式的运算符优先级整体提升。
写在最后
下一篇go系列文章开始学习流程控制、函数、数组、切片等内容。