目录
一、概述
为什么需要变量?
- 一个程序就是一个世界
- 变量是程序的基本组成单位
- 不论是使用哪种高级程序语言编写程序,变量都是其程序的基本组成单位。
变量相当于内存中一个数据存储空间的表示,你可以把变量看做是一个房间的门牌号,通过门牌号我们可以找到房间,同样的道理,通过变量名可以访问到变量(值)。
声明变量
基本语法:var 变量名 数据类型
1、变量使用注意事项
- 变量表示内存中的一个存储区域
- 该区域有自己的名称(变量名)和类型(数据类型)
- Golang变量使用的三种方式
- 指定变量类型,声明后若不赋值,使用默认值
- 根据值自行判定变量类型(类型推导)
- 省略var,注意:=左侧的变量不应该是已经声明过的,否则会导致编译错误
- 多变量声明,一次性声明多个变量
- 该区域的数据值可以在同一类型范围内不断变化
- 变量在同一个作用域(一个函数或者代码块)内不能重名
- 变量=变量名+值+数据类型
- Golang的变量如果没有赋初值,编译器会使用默认值,比如int默认值0,string默认值为空串
- 不能改变数据类型存储
package main
import "fmt"
//全局变量
var m1=100
var m2=24.5
var m3="marry"
//一次性声明
var (
x1=100
x2=24.5
x3="marry"
)
func main(){
var i int
fmt.Println("i=",i)
var num=10.11
fmt.Println("num=",num)
name :="tom"//等价于:var name string name="tom"
fmt.Println("name=",name)
//var n1,n2,n3 int
//var n1,n2,n3=100,"tom",33.20
n1,n2,n3 :=100,"tom",33.20
fmt.Println("n1=",n1,"n2=",n2,"n3=",n3)
}
程序中+号的使用
- 当左右两边都是数值型时,则做加法运算。
- 当左右两边都是字符串,则做字符串拼接。
2、变量的数据类型
每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间。
数据类型
- 基本数据类型
- 数值型
- 整数类型(int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64,byte)
- 浮点类型(float32,float64)
- 字符型(没有专门的字符型,使用byte来保存单个字母字符)
- 布尔型(bool)
- 字符串(string)
- rune://int32的别名,表示一个Unicode码点
- byte://uint8的别名
- complex64,complex128
- 数值型
- 派生/复杂数据类型
- 指针(Pointer)
- 数组
- 结构体(struct)
- 管道(Channel)
- 函数(也是一种类型)
- 切片(slice)
- 接口(interface)
- map
- note
注:在Golang中,官方文档将string归属在基本数据类型
基本数据类型默认值
- 整型 默认值:0
- 浮点型 默认值:0
- 字符串 默认值:""
- 布尔类型 默认值:false
3、整型的使用细节
- Golang各整数类型分:有符号和无符号。
- Golang的整型默认声明为int型
- Golang程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型[如:年龄]
- bit:计算机中的最小存储单位。byte:计算机中基本存储单元。
- 如何在程序中查看某个变量的占用字节大小和数据类型
package main
import (
"fmt"
"unsafe"
)
func main(){
var n1 = 100
fmt.Printf("n1的类型 %T,n1占用的字节数是 %d ",n1,unsafe.Sizeof(n1))
}
4、浮点类型
- Golang的浮点类型可以表示一个小数。
- 小数类型就是用于存放小数的,比如:1.2
浮点型的分类
- 单精度float32,占用存储空间:4字节,表数范围:-3.403E38~3.403E38
- 双精度float64,占用存储空间:8字节,表数范围:-1.798E308~1.798E308
说明一下:
- 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位 说明:浮点数都是有符号的
- 尾数部分可能丢失,造成精度损失。说明:float64的精度比float32的要准确,如果要保存一个精度高的数,则应该选用float64
- 浮点型的存储分为三部分:符号位+指数位+尾数位 在存储过程中,精度会丢失
package main
import (
"fmt"
)
func main(){
var price float32 = 90.34
fmt.Println("price",price)
var num1 float32 = -123.0000901
var num2 float64 = -123.0000901
fmt.Println("num1=",num1,"num2=",num2)//num1= -123.00009 num2= -123.0000901
}
浮点类型使用细节
- Golang的浮点类型有固定的范围和字节长度,不受具体的操作系统的影响。
- Golang的浮点类型默认声明为float64类型。
- 浮点型常量有两种表示形式
- 十进制数形式:如:5.12 .512 (必须有小数点)
- 科学计数法形式:如:5.1234e2=5.12*10的2次方 5.12E-2=5.12/10的2次方
- 通常情况下,应该使用float64,因为它比float32更精确。
5、字符类型(char)
Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字符连接起来的。也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的。
package main
import (
"fmt"
)
func main() {
var c1 byte ='a'
var c2 byte ='0'
fmt.Println("c1=",c1,"c2=",c2)//c1= 97 c2= 48
fmt.Printf("c1=%c c2=%c\n",c1,c2)//c1=a c2=0 输出字符,使用格式化输出
var c3 int ='北'
var c4 int =22269
fmt.Printf("c3=%c c4=%c\n",c3,c4)//c3=北 c4=国
var n1=10 +'a'
fmt.Println("n1=",n1)//n1= 107
}
字符类型使用细节
- 字符常量是用单引号''括起来的单个字符。
- Go中允许使用转义字符''来将其后的字符转变为特殊字符型常量。
- Go语言的字符使用UTF-8编码英文字母1个字节,汉字3个字节
- 在Go中字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值。
- 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的unicode字符
- 字符类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码。
- 字符型存储到计算机中,需要将字符对应的码值找出来。 存储:字符-->码值-->二进制-->存储 读取:二进制-->码值-->字符-->读取
- 字符和码值的对应关系是通过字符编码表决定的(是规定好的)
6、布尔类型:bool
- 布尔类型也叫bool类型,bool类型数据只允许值true和false
- bool类型占1个字节
- bool类型适用于逻辑运算,一般用于程序流程控制
- 不可以0或非0的整数替代false和true,这点和c语言不同
package main
import (
"fmt"
"unsafe"
)
func main(){
var f =false
fmt.Printf("f的类型 %T,f占用的字节数是 %d ",f,unsafe.Sizeof(f))//f的类型 bool,f占用的字节数是 1
}
7、字符串类型:string
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本
-
字符串一旦赋值了,字符串就不能修改了,在Go中字符串是不可变的
-
字符串的两种表现形式
- 双引号,会识别转义字符
- 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
-
字符串的拼接方式 +
-
当一行字符串太长时,需要使用到多行字符串,+号留在上一行
二、类型转换
1、基本数据类型的转换
Golang和Java/c不同,Go在不同类型的变量之间赋值时需要显式转换。也就是说Golang中数据类型不能自动转换
基本语法:
表达式 T(v):将值v转换为类型T
T:就是数据类型,比如int32,int64,float32等等
v:就是需要转换的变量
例:
var i int =42
var f float64 = float64(i)
var u uint8 = uint8(f)
fmt.Println(i,f,u)
- Go中,数据类型的转换可以是从表示范围小-->表示范围大,也可以 范围大-->范围小
- 被转换的是变量存储的数据(即值),变量本身的数据类型没有变化!
- 在转换中,比如将int64转成int8,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。因此在转换时,需要考虑范围。
var n1 int32 = 12
var n2 int8 =int8(n1) + 127//编译通过,但是结果不是127+12 按溢出处理
fmt.Println(n1,n2)
2、基本数据类型和string的转换
2.1、基本数据类型转string
方式1:
"fmt"下的Sprintf方法
func Sprintf(format string, a ...interface{}) string
:Sprintf根据format参数生成格式化的字符串并返回该字符串。
-----------------------------------------------------
package main
import (
"fmt"
)
func main() {
var n1 int = 99
var n2 float64 =23.45
var b bool = true
var c byte = 'a'
var str string
str=fmt.Sprintf("%d",n1)
fmt.Printf("str type %T value=%v\n",str,str)
str=fmt.Sprintf("%.2f",n2)
fmt.Printf("str type %T value=%v\n",str,str)
str=fmt.Sprintf("%t",b)
fmt.Printf("str type %T value=%v\n",str,str)
str=fmt.Sprintf("%c",c)
fmt.Printf("str type %T value=%v\n",str,str)
}
方式2:
使用strconv包的函数
func Itoa(i int) string:Itoa是FormatInt(i, 10) 的简写。
func FormatBool(b bool) string:根据b的值返回"true"或"false"。
func FormatInt(i int64, base int) string:返回i的base进制的字符串表示。base 必须在2到36之间,结果中会使用小写字母'a'到'z'表示大于10的数字。
func FormatUint(i uint64, base int) string:是FormatInt的无符号整数版本。
func FormatFloat(f float64, fmt byte, prec, bitSize int) string:函数将浮点数表示为字符串并返回。
bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入。
fmt表示格式:'f'(-ddd.dddd)、'b'(-ddddp±ddd,指数为二进制)、'e'(-d.dddde±dd,十进制指数)、'E'(-d.ddddE±dd,十进制指数)、'g'(指数很大时用'e'格式,否则'f'格式)、'G'(指数很大时用'E'格式,否则'f'格式)。
prec控制精度(排除指数部分):对'f'、'e'、'E',它表示小数点后的数字个数;对'g'、'G',它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。
---------------------------------------------------------------------
package main
import (
"fmt"
"strconv"
)
func main() {
var n1 int64 = 99
var n2 float64 =23.45
var b bool = true
var n3 uint64 = 123
var str string
str = strconv.FormatInt(n1,10)
fmt.Printf("str type %T value=%v\n",str,str)
str = strconv.Itoa(int(n1))
fmt.Printf("str type %T value=%v\n",str,str)
str = strconv.FormatFloat(n2,'f',10,64)//说明:'f':格式 10:表示小数位保留10位 64:表示这个小数是float64
fmt.Printf("str type %T value=%v\n",str,str)
str = strconv.FormatBool(b)
fmt.Printf("str type %T value=%v\n",str,str)
str = strconv.FormatUint(n3,10)
fmt.Printf("str type %T value=%v\n",str,str)
}
2.2、string类型转基本数据类型
使用strconv包的函数
func ParseBool(str string) (value bool, err error):返回字符串表示的bool值。它接受1、0、t、f、T、F、true、false、True、False、TRUE、FALSE;否则返回错误。
func ParseInt(s string, base int, bitSize int) (i int64, err error):返回字符串表示的整数值,接受正负号。
base指定进制(2到36),如果base为0,则会从字符串前置判断,"0x"是16进制,"0"是8进制,否则是10进制;
bitSize指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64;返回的err是*NumErr类型的,如果语法有误,err.Error = ErrSyntax;如果结果超出类型范围err.Error = ErrRange。
func ParseUint(s string, base int, bitSize int) (n uint64, err error):ParseUint类似ParseInt但不接受正负号,用于无符号整型。
func ParseFloat(s string, bitSize int) (f float64, err error):解析一个表示浮点数的字符串并返回其值。
如果s合乎语法规则,函数会返回最为接近s表示值的一个浮点数(使用IEEE754规范舍入)。bitSize指定了期望的接收类型,32是float32(返回值可以不改变精确值的赋值给float32),64是float64;返回值err是*NumErr类型的,语法有误的,err.Error=ErrSyntax;结果超出表示范围的,返回值f为±Inf,err.Error= ErrRange。
-------------------------------------------------------------------------------
package main
import (
"fmt"
"strconv"
)
func main() {
var str string = "true"
var b bool
b , _ = strconv.ParseBool(str)
fmt.Printf("b type %T value=%v\n",b,b)
str = "1234567"
n1, _ := strconv.ParseInt(str,10,0)
fmt.Printf("n1 type %T value=%v\n",n1,n1)
str = "123.35"
f1, _ := strconv.ParseFloat(str,64)
fmt.Printf("f1 type %T value=%v\n",f1,f1)
}
注意:在将string类型转成基本数据类型时,要确保string类型能够转成有效的数据。例:不能把"hello"转成一个整数,如果这样做Golang直接将其转换成0.其他类型也是一样的道理,没有转成功,则转成默认值。
干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!