变量的定义及使用
变量定义语法: var 变量名 数据类型
局部变量:定义在语句块中(如方法)的变量
全局变量:定义在语句块外的变量
变量声明方式:
- 指定变量类型,声明后如果不赋值则使用默认值
- 根据值自行判断变量类型
- 省略var 使用 := 赋值,左侧变量不能是已经声明过的,否则报错
- 支持多变量声明(局部变量和全局变量都支持),见示例代码
示例代码
//全局变量声明
var gn1 = 100
var gn2 = "jack"
//一次声明多个全局变量
var (
gn3 = 200
gn4 = "mary"
)
func test(){
//变量使用方式1:指定变量类型,声明后如果不赋值则使用默认值
var i int
fmt.Println("i1=",i)
//变量使用方式2:根据值自行判断变量类型
var i2 = 2
fmt.Println("i2=",i2)
//变量使用方式3:省略var 使用 := 赋值,左侧变量不能是已经声明过的,否则报错
i3 := "4"
fmt.Println("i3=",i3)
//一次声明多个变量 方式1
var n1, n2, n3 int
fmt.Println("n1=",n1,"n2=",n2,"n3=",n3)
//一次声明多个变量 方式2
var n12, n22, n32 = 100, "tom", 200
fmt.Println("n1=",n12,"n2=",n22,"n3=",n32)
//一次声明多个变量 方式3
n13, n23, n33 := 200, "tom", 300
fmt.Println("n1=",n13,"n2=",n23,"n3=",n33)
//输出全局变量
fmt.Println("全局变量:gn1=",gn1,"gn2=",gn2,"gn3=",gn3,"gn4",gn4)
n13 = 133
//n13 = n23; 该行报错,不能改变变量的类型
}
基本数据类型
基本数据类型,包括
1)数值型:整型:int、int8、int16、int32、int64 浮点型:float32、float64
2)字符型:没有专门字符型,用byte来保存单个字母字符
3)布尔型: true false
4)字符串:String 官方将字符串定义为基本类型
派生/复杂数据类型,包括:
1)指针 pointer
2)数组
3)结构体 struct
4)管道 Channel
5)函数
6)切片 slice
7)接口 interface
8)map
整型
存放整数的变量,包括有符号整型、无符号整型、其他类型整型,默认值0
有符号整型:
无符号整型:
其他类型整型:
示例代码:
func test2(){
var i int
fmt.Println("i=",i);
//有符号整型测试
//var i2 int8 = 128 // 报错超过 constant 128 overflows int8
var i2 int8 = 127 //正常
fmt.Println("i2=",i2);
//无符号整型测试
//var i3 uint8 = 256 // 报错超过 constant 256 overflows uint8
//var i3 uint8 = -1 //报错 constant -1 overflows uint8
var i3 uint8 = 255 //正常
fmt.Println("i23=",i3);
//其他类型整型
var a int = 999
fmt.Println("a=",a);
var b unit = 1
var c byte = 255
fmt.Println("a=",a,"b=",b,"c=",c);
}
注意点
- int 和 uint 大小和系统有关,其他类型范围和系统无关
- 整数声明默认类型是整形
- 通过如下方式查看变量大小和占用字节数
fmt.Printf(“i3的类型 %T 占用的字节数是 %d”, i3, unsafe.Sizeof(i3)) - Golang 程序中整型变量在使用时,在满足程序正常运行的前提下尽量使用占用空间小的数据类型
浮点型
用来存放小数的数据类型
浮点类型在机器中的保存形式:浮点数=符号位+指数位+尾数位
默认值0
分类
示例代码
func test3(){
var price float32 =12.13
fmt.Println("price=",price);
var price2 float32 =-0.000098
var price3 float64 =-8999.09
fmt.Println("price2=",price2,"price3=",price3)
//精度丢失测试
var price4 float32 =12.130000901
var price5 float64 =12.130000901
//输出 price4= 12.130001 price5 12.130000901 float32 发生精度丢失
//float64 精度比 float32 精度高
fmt.Println("price4=",price4,"price5",price5)
var num float64 = 5.12334423e2
var num2 float64 = 5.123344233E-2
}
注意点
- 浮点数是有符号的
- 位数部分可能会丢失,造成精度丢失 float64精度不float32要高
- 浮点类型默认声明为 float64
- 浮点型两种常用的表示形式:
十进制:5.12 .512 必须有小数点
科学计数法:5.123e2 = 5.12*10的2次方 5.123E-2 = 5.12/10 的2次方 E 可以大写也可以小写
字符类型
Golang中没有专门的字符类型,如果要存储某个字符一般使用byte来保存,字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串室友单个字节连接起来的。
示例代码
func test01(){
var c1 byte = 'a'
var c2 byte = '0'
fmt.Println("c1=",c1);
fmt.Println("c2=",c2);
//c1= 97 c2= 48 tyte输出时默认输出码值 如果希望输出字符串 需要格式化输出
fmt.Printf("c2= %c c1= %c",c2,c1) //c2= 0 c1= a
//var c3 byte = '北' // 报错 constant 21271 overflows byte
var c3 = '北' // 字符被默认成int32 类型
fmt.Println("c3 =",c3);
fmt.Printf("c3的类型 %T 占用的字节数是 %d", c3, unsafe.Sizeof(c3))
//输出:c3的类型 int32 占用的字节数是 4
var num = 10 + 'a'
fmt.Println("num = ", num )//输出 107
}
注意点
- 如果我们保存的字符在 ascii表中,可以直接保存到byte,如果字符的对应码大于255 可以使用int类型保存。
- go语言中的字符使用UTF-8 编码(英文1字节 汉字3字节),如果想查询字符对应的utf-8码值 访问: http://www.mytju.com/classcode/tools/encode_utf8.asp
- go中字符本质上是一个整数,直接输出时是输出该字符对应的UTF-8 编码的值。输出字符需要格式化输出 fmt.Printf(“c2= %c c1= %c”,c2,c1)
- 可以直接将整数赋值给变量然后格式化输出对应字符
- 字符类型是可以进行运算的相当于一个整数。
- 字符型 存储到计算机中 需要将字符对应的码值 转换为2进制进行存储。
存储:字符 ->码值-> 二进制-> 存储 读取:和存储刚好相反 - 字符和码值的关系是通过字符编码表确定的(事先约定好的)
- Go语言编码统一使用utf-8 非常方便 没有乱码的困扰
布尔类型
bool类型只允许 true 和 false 两种取值,占一个字节,
默认值:false
示例代码
func test02(){
var b = false
fmt.Println(b)
//b的类型 bool 占用的字节数是 1
fmt.Printf("b的类型 %T 占用的字节数是 %d",b , unsafe.Sizeof(b))
}
string类型
字符串是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。字节使用UTF-8编码标识Unicode文本
默认值:""
示例代码
func test03(){
var str string = "北京欢迎你1"
//str ="haha "
fmt.Println(str[0])//229
//str[0] = 1 报错 字符串内容无法修改
//str的类型 string 占用的字节数是 16
fmt.Printf("str的类型 %T 占用的字节数是 %d",str , unsafe.Sizeof(str))
var str2 string =`adasdfa\n \t`
var str3 string ="adasdfa\n \t"
fmt.Println(str2)//输出 16adasdfa\n \t 不会通过 \转义字符
fmt.Println(str3)//输出 16adasdfa
str = str + "123"
fmt.Println(str)
str += "haha"
fmt.Println(str)
//当一个字符串很长时,可以通过加号分行写 但是加号要写在上一行
var str5 = "haha" +
"hah123" + " test "+
"asdfas"
fmt.Println(str5)
}
注意点
- 字符串赋值后不能修改 其内容(其中某个字节内容)
- 两种字符串定义方式 “123\n”
123\n
(不会转义字符)
基本数据类型转换
Golang中不支持变量类型的自动转换,必须显式转换
基本语法: 表达式 T(v) 将值v 转换为类型T
示例代码
func test04(){
var i int32 = 100
var f float32 = float32(i)
fmt.Println(f)//100
//i的类型 int32 占用的字节数是 4
fmt.Printf("i的类型 %T 占用的字节数是 %d",i , unsafe.Sizeof(i))
var n1 int32 = 10
var n2 int64
//n2 = n1 +10 会报错 因为类型不符
n2 = int64(n1)+10
fmt.Println("n2 = ",n2)//20
var n4 = 200
var n3 int8 =10
n3 = int8(n4)+10
fmt.Println("n3 = ",n3)//-46 由于类型范围问题 导致计算结果不准
//--------------基本类型 转string
var i1 int =99
var f1 float32 =32.23
var b bool = true
var c1 byte = 'a'
var str string
str = fmt.Sprintf("%d",i1)
fmt.Println("str = ",str)
fmt.Printf("str的类型 %T 占用的字节数是 %d \n",str , unsafe.Sizeof(str))
str = fmt.Sprintf("%f",f1)
fmt.Println("str = ",str)
fmt.Printf("str的类型 %T 占用的字节数是 %d \n",str , unsafe.Sizeof(str))
str = fmt.Sprintf("%t",b)
fmt.Println("str = ",str)
fmt.Printf("str的类型 %T 占用的字节数是 %d \n",str , unsafe.Sizeof(str))
str = fmt.Sprintf("%c",c1)
fmt.Println("str = ",str)
fmt.Printf("str的类型 %T 占用的字节数是 %d \n",str , unsafe.Sizeof(str))
str = strconv.FormatInt(int64(i1),10)
str = strconv.FormatBool(b)
str = strconv.FormatFloat(float64(f1),'f',10,64)
//-----------string转基本类型
var ss string = "123"
var ss2 string = "true"
var ss3 string ="123.123"
var in1,_ = strconv.ParseInt(ss,10,64)
fmt.Println(in1)
var bo,_ = strconv.ParseBool(ss2)
fmt.Println(bo)
var fl,_ = strconv.ParseFloat(ss3,64)
fmt.Println(fl)
}
注意点
- 普通类型转字符串两种方式
调用fmt.Sprintf("%t",b)
调用 strconv.FormatBool(b) - 字符串转普通类型 直接嗲用strconv包的方法,如: strconv.ParseInt(ss,10,64)
- 字符串转基本类型时要确保字符串格式正确,如不能吧hello 转成int类型, 其他类型也类似 float 转为0 boolean 转为false
指针类型
基本数据类型变量存的是值也叫值类型。指针变量存的是一个地址,这个地址指向的空间存的才是值。
var ptr *int = &num //表示用ptr 变量保存 num变量的值的地址
示例代码
func test4(){
var i int = 10
fmt.Println("i的地址=",&i)
var ptr = &i
fmt.Println("i的地址=",ptr)
fmt.Println("ptr的地址=",&ptr)
fmt.Println("ptr指针地址保存的值=",*ptr)
//ptr的类型 *int 占用的字节数是 8
fmt.Printf("ptr的类型 %T 占用的字节数是 %d", ptr, unsafe.Sizeof(ptr))
}
注意点
- 获取变量地址 用 &符号 ,如: &num 就是num变量值保存的地址
- 指针类型表示的是一个内存地址,所有值类型(包括:整型、浮点型、bool型、string 数组、结构体)的变量都有对应的指针类型,形式为:*变量类型,如: *int * int8 * int32 * int64 * float32
- 获取指针变量 所保存地址的值 使用 * ,如:*ptr 获取指针ptr 指向地址中保存的值
值类型和引用类型
值类型:包括:整型、浮点型、bool型、string 数组、结构体 变量地址中直接保存值,内存通常在栈中分配,内存示意图如下:
引用类型:变量存储的是一个地址,这个地址对应的空间保存的才是真正的值,当没有任何变量引用这个地址时 该值会作为来及被回收。通常在堆区分配空间,内存示意图如下:
标识符及命名规范
标识符
Golang 对各种变量、方法、函数等的命名使用的字符串成为标识符
命名规则
- 由大小写字母、0-9和_ 组成
- 数字不可以开头
- 严格区分大小写
- 不能包含空格
- 单个下划线"_",在Go中是一个特殊的标识符,称为空标识符,可以代表任何标识符,仅做占位使用,无法通过这个标识符进行变量或方法的调用(它代表的取值永远不会被调用)如:方法返回多个值,有的值不需要时 可以使用 _ 来占位 。仅做占位符,不做标识符用
命名规范
- 包名和目录保持一致,尽量采用简短有意义的包名,不用和标准包冲突
- 变量函数等使用驼峰命名法
- Go中如果变量、函数、常量名首字母大写,则表示可以被其他包访问(相当于java中的public)。否则只能在本包使用(相当于 protected private 等)
- 不使用保留关键字和预定义标识符
保留关键字
预定义标识符