变量的介绍
变量相当于内存中一个数据存储空间的表示,像门牌号,通过门牌号找到房间(值)
- 变量的使用
- 定义变量
- 给变量赋值
- 使用变量
- 变量的使用三种方式
- 指定变量类型,声明后不赋值,使用默认值
- 根据值自 推导变量类型
- :=的方式定义未曾定义过的变量
var i int //0
var num= 10.11
fmt.Println(num)
fmt.Println(reflect.TypeOf(num)) //10.11 float64
name := "zhangsan"
- 多变量的声明 n1,n2,n3 := 1,”2”,3.3
- 一次性声明多个全局变量
var n1 = 100
var n2 = 101
var (
n3 = 1
n4 = "test"
)
var n1,name,n6 = 100, "test", 888
- 改变值的前提是类型一致
- 变量在同一个作用域内不能重命名
- 变量三要素:变量=变量名+值+数据类型
- 变量的默认值:int为0,string为空字符串,小数为0
变量是什么,初始化和赋值
声明变量: var 变量 类型
var a int
var num1 float32
初始化变量
var a int = 45
var b = 400 //声明时候就赋值,忽略数据类型
给变量赋值
已经定义过 var num int //0
num = 12
+号
- 左右两边都是数值型,加法
- 左右两边都是字符串,字符串拼接
数据类型
Go中都是utf-8的编码,所以btye存单个字母。
- byte是utf8的别名
- rune是int32的别名
4.1 整数类型
- 简单的说,就是用于存放整数值的,比如 0, -1, 2345 等等
1个字节8位,第一位表示符号,后七位表示值,-2的7次方到2的7次方-1
2个字节8位,第一位表示符号,后15位表示值,-2的15次到2的15次方-1
2的8次方-1(0)
var a int = 8900
var b uint = 1
var c byte = 255
var d rune = 255
var num5 = 11.1
fmt.Printf("%T",num5) //64
1- 整型的使用细节
- Golang 各整数类型分:有符号和无符号,int uint 的大小和系统有关
- Golang 的整型默认声明为 int 型
- 如何在程序查看某个变量的字节大小和数据类型
- Golang 程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型。【如:年龄 byte】
- Bit 计算机找那个最小的存储单位,byte计算机基本存储单元,1byte=8 bit
var n1 = 100
fmt.Printf("类型%T",n1)
var n2 int64 = 10
fmt.Printf("类型%T 占的字节数%d",n1,unsafe.Sizeof(n2))
//类型int 占的字节数8 64位8个字节
4.2 小数类型/浮点型
小数类型就是用于存放小数的,比如 1.2 0.23 -1.911
var price float32 = 89.11
fmt.Println(price)
var num3 float32 = -123.0000901
var num4 float64 = -123.0000901
//-123.00009
//-123.0000901
1- 小数类型分类
- 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位说明:浮点数都是有符号的.
- 尾数部分可能丢失,造成精度损失。 -123.0000901
- 64位精度大于32位
2-浮点型使用细节
浮点类型有固定的范围和字段长度,不受具体 OS(操作系统)的影响
浮点型默认声明为 float64 类型
1) 浮点型常量有两种表示形式
十进制数形式:如:5.12 .512 (必须有小数点)
科学计数法形式:如:5.1234e2 = 5.12 * 10 的 2 次方 5.12E-2 = 5.12/10 的 2 次方
2) 通常情况下,应该使用 float64 ,因为它比 float32 更精确。[开发中,推荐使用 float64]
num6 := 5.12
num7 :=.123
fmt.Println(num6,num7)
//num8:=5.1234e2
//fmt.Println(num8)
num6 := 5.12
num7 :=.123
fmt.Println(num6,num7)
num8:=5.1234e2 //10^2
num9:=5.1234E2 //10^2
num10:=5.1234E-2 //除以10^2
fmt.Println(num8,num9,num10)
4.3 字符类型
1-基本介绍
Golang 中没有专门的字符类型,如果要存储单个字符(字母),一般使用 byte 来保存。
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而 Go 的字符串不同,它是由字节组成的。
直接输出byte值,就是输出了对应的字符的码值,希望输出对应的字符,需要使用格式化输出
var c1 byte ='a'
var c2 byte ='0'
fmt.Println(c1,c2)//97 48
var c1 byte ='a'
var c2 byte ='0'
fmt.Println(c1,c2)
fmt.Printf("c1=%c c2=%c\n",c1,c2)
//var c3 byte = "北"//溢出 21271
var c3 int = '北'
fmt.Printf("c3=%c 对应的码值=%d",c3,c3)
- 如果我们保存的字符在 ASCII 表的,比如[0-1, a-z,A-Z..]直接可以保存到 byte
- 如果我们保存的字符对应码值大于 255,这时我们可以考虑使用 int 类型保存
- 如果我们需要安装字符的方式输出,这时我们需要格式化输出,即 fmt.Printf(“%c”, c1)..
2- 字符类型使用细节
- 字符常量是用单引号(‘’)括起来的单个字符。例如:var c1 byte = ‘a’ var c2 int = ‘中’ var c3 byte = ‘9’
- Go 中允许使用转义字符 ‘'来将其后的字符转变为特殊字符型常量。例如:var c3 char = ‘\n’ // ‘\n’表示换行符
- Go 语 言 的 字 符 使 用 UTF-8 编 码 , 如 果 想 查 询 字 符 对 应 的 utf8 码 值www.mytju.com/classcode/tools/encod...
英文字母-1 个字节 汉字-3 个字节
- 在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
- 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的 unicode 字符
- 字符类型是可以进行运算的,相当于一个整数,因为它都对应有 Unicode 码
n1 =10+ 'a' n1=107
3- 字符类型本质探讨
- 字符型 存储到 计算机中,需要将字符对应的码值(整数)找出来
存储:字符—>对应码值—->二进制–>存储
读取:二进制—-> 码值 —-> 字符 –> 读取
- 字符和码值的对应关系是通过字符编码表决定的(是规定好)
- Go 语言的编码都统一成了 utf-8。非常的方便,很统一,再也没有编码乱码的困扰了
4.4 布尔类型
- bool类型,只允许true和false
- bool类型占1个字节
- bool类型适于逻辑运算,流程控制
4.5 String类型
Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本
var address string ="golang"
注意:
- Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本,这样 Golang 统一使用 UTF-8 编码,中文乱码问题不会再困扰程序员。
- 字符串一旦赋值了,字符串就不能修改了:在 Go 中字符串是不可变的
- 字符串的两种表示形式
- 双引号, 会识别转义字符
- 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
- 字符串拼接 【+、+=】
- 一行太长,用字符串连接【分行写】
var str = "hello"
str[0] = 'a'//go中字符串不能修改
str1 := "测试\n测试"
str2 := `
func main(){
fmt.Println(123)
}
`
fmt.Println(str1)
fmt.Println(str2)
//
//测试
//测试
// func main(){
// fmt.Println(123)
//}
str3:= "hello" +" go"
str3 += " language"
fmt.Println(str3)
var str string = "张维双"
fmt.Println(str)
//var str1 string = "hello"
//str1[0] = "a"
str3 := "abc\nabc"
str4 := `abc\nabc`
fmt.Println(str3)
fmt.Println(str4)
str5 := "hello" + "world"
str5 += str5
fmt.Println(str5)
1-基本数据类型的默认值
变量没有赋值,会有默认值
var a int//0
var b string//""
var c float32//0
var d float64//0
var happy bool//false
var name string//""
fmt.Printf("a=%d,b=%v,c=%v,d=%v,happy=%v,name=%v",a,b,c,d,happy,name)
2-基本数据类型的相互转换
Go中数据类型只能显式转换,不能自动转换
表达式T(v) 将值v转换为类型T
T:数据类型,比如int32,int64,float32等
V:需要转换的变量
var i int32 = 100
var n1 float32 = float32(i)
var n2 float64 = float64(i)
var n3 int8 = int8(i)
var n4 int64 = int64(i)
fmt.Printf("n1=%v,n2=%v,n3=%v,n4=%v",n1,n2,n3,n4)//100
fmt.Printf("%T",i)//int32
fmt.Println(i)//100 //只是把值给了其他变量,但是自身的类型和值没有变化
var num1 int64 = 999999
var num2 int8 = int8(num1)
fmt.Println(num2)//63
注意:
- 数据类型的转换可以从小范围转为大范围,也可从大范围转小范围
- 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化
- 在转换中,比如将 int64转成 int8 【-128—127】 ,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。 因此在转换时,需要考虑范围.
- 只有相同类型才能相加,比如
var n1 int32 = 1 |var n2 int64 | varn3=n1+n3
练习
var n1 int32 = 12
var n2 int64
//n2 = n1 + 20 //int32+20 int32!=int64 编译不通过
n2 = int64(n1) + 20
fmt.Println(n2)
var n1 int32 = 12
var n3 int8
var n4 int8
n4 = int8(n1) + 127 //编译通过,结果不是127+12 ,按溢出处理
n3 = int8(n1) + 128 //编译不通过,n3 int8 【-128---127】,直接检测就报错了
fmt.Println(n4)
3-基本数据类型和 string 的转换
我们经常将基本数据类型转成 string,或者将 string 转成基本数据类型。
(整型、浮点型、字符串、布尔)
基本类型转 string 类型
方式 1:fmt.Sprintf(“%参数”, 表达式) 【个人习惯这个,灵活】
参数需要和表达式的数据类型相匹配
fmt.Sprintf().. 会返回转换后的字符串
//基本数据类型转string
var num1 int = 99
var num2 float64 = 23.456
var b bool = true
var myChar byte = 'h'
var str string
//第一种方式 fmt.Sprintf方法
str = fmt.Sprintf("%d", num1) //转的是值
fmt.Printf("str type %T and str=%v\n", str, str) //str type string and str=99
str = fmt.Sprintf("%f", num2)
fmt.Printf("str type %T and str=%v\n", str, str) //str type string and str=23.456000
str = fmt.Sprintf("%t", b)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="true"
str = fmt.Sprintf("%c", myChar)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="h"
方式2:strconv包的函数
func FormatBool(b bool) string
func FormatInt(i int64, base int) string
func FormatUint(i uint64, base int) string
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
//第二种 strconv
var num3 int = 99
var num4 float64 = 23.456
var b2 bool = true
str := strconv.FormatInt(int64(num3), 10)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="99"
str = strconv.FormatFloat(num4, 'f', 10, 64) //f 展示的格式 ,10:小数点后10位,64:float64
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="23.4560000000"
str = strconv.FormatBool(b2)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="true"
var num5 int = 4567
str = strconv.Itoa(num5)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="4567"
var num6 int64 = 4567
str = strconv.Itoa(int(num6))
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="4567"
4- string 类型转基本数据类型
func ParseBool(str string) (value bool, err error)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (n uint64, err error)
func ParseFloat(s string, bitSize int) (f float64, err error)
func ParseInt
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。
//string转其他基本类型
var str string = "true"
var b bool
b, _ = strconv.ParseBool(str)
fmt.Printf("b type %T and b=%v \n", b, b) //str type string and str="4567"
var str2 string = "1234590"
var n1 int64
var n2 int
n1, _ = strconv.ParseInt(str2, 10, 64)
n2 = int(n1)
fmt.Printf("n1 type %T n1=%v\n", n1, n1)
fmt.Printf("n2 type %T n2=%v\n", n2, n2)
var str3 string = "123.456"
var f1 float64
f1, _ = strconv.ParseFloat(str3, 64)
fmt.Printf("f1 type %T f1=%v\n", f1, f1)
5- string 类型转基本数据类型的注意事项
注意,string转基本数据类型的时候,要考虑到有效性,否则会返回类型 的默认值
"123"转整型 123
"hello"转整型 0
var str string = "hello"
var n int64
n, _ = strconv.ParseInt(str, 10, 64)
fmt.Printf("n type %T n=%v\n", n, n)
//n type int64 n=0
var str string = "hello"
var b bool = true
b, _ = strconv.ParseBool(str)
fmt.Printf("b type %T, b=%v\n", b, b)
//b type bool, b=false
指针
1-基本介绍
//基本数据类型在内存布局
var n int = 10
//n 的地址是什么,&n
fmt.Println("n 的地址=", &n) //n 的地址= 0xc0000a2058
//ptr是一个指针变量
//ptr的类型 *int
//ptr 本身的值&n
var ptr *int = &n
fmt.Printf("ptr=%v\n", ptr) //ptr=0xc0000a2058
fmt.Printf("ptr的地址=%v\n", &ptr) //ptr的地址=0xc000006030
fmt.Printf("ptr指向的值=%v\n", *ptr) //ptr指向的值=10
- 基本数据类型,变量存的就是值,也叫值类型
- 获取变量的地址,用&,比如 var num int,取地址 &num
- 内存布局如下
指针类型,指针变量存的是这个地址,这个地址指向的空间存的才是值 var ptr *int = &num
- 获取指针类型所指向的值,使用:* 比如 var ptr int ,使用ptr获取p指向的值
- 指针在内存布局如下
说白了
指针变量内存中存的是地址,这个地址又有真的值
导致指针变量能取地址 &ptr
又能取值 *ptr
2-指针类型的细节
- 值类型,都有对应的指针类型 【数据类型 int–int float–*float】
- 值类型包括:基本数据类型【int\string\boll\float】+数组+结构体struct
- 引用类型:指针、slice切片、map、管道chan、interface等都是引用类型
3-值类型和引用类型
- 值类型包括:基本数据类型【int\string\boll\float】+数组+结构体struct
- 引用类型:指针、slice切片、map、管道chan、interface等都是引用类型
4- 值类型和引用类型的使用特点
内存中分两大块,一块叫栈区、一块叫堆区
- 值类型,变量直接存储值,值类型数据,通常是在栈区上分配
- 引用类型,变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,单没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收
标识符
1-概念
- Golang 对各种变量、方法、函数等命名时使用的字符序列称为标识符
- 凡是自己可以起名字的地方都叫标识符
2-标识符的命名规则
- 由26个英文祖玛大小写,0-9,_组成
- 数字不可用开头 var 3num int
- Golang 中严格区分大小写
- 标识符不能包含空格
- 下划线,空标识符,忽略某个值,被占用,但是可以用_num,【int、float32在这种不推荐】
- 不能以系统保留关键字作为标识符(25个),【break 、if】
3-标识符的命名规范
- 包名:保持package的名字和目录一致、不要和标准库冲突
- 变量名、函数名、常量名使用驼峰法
- 变量名、函数名、常量名首字母大写能被其他的包访问
- 变量名、函数名、常量名首字母小写只能被本包使用