2 变量运算符-基本数据类型讲解【Go语言教程】
2.1 变量
2.1.1 声明变量方式
- 指定变量类型,声明后若不赋值,使用默认值
- 类型推导
- 通过
:=
- 多变量声明
- 全局变量定义
在函数外部定义的就是全局变量
变量=变量名+值+数据类型
注意:如果go程序报错:
package 'xxx' is not in GOROOT
- 执行
go mod init
即可
2.2 基本数据类型
2.2.1 整数
①int的有符号类型
②int的无符号类型
③int的其他类型
- 整型的使用细节:
- Golang 各整数类型分:有符号和无符号,int uint 的大小和系统有关。
- Golang整型默认声明为int
- 在程序中查看某个变量的字节大小和数据类型
package main
import (
"fmt"
"unsafe"
)
// var (
// address = "北京"
// sex int = 1
// )
func main(){
var n2 uint = 68
fmt.Printf("n的类型为 %T, n2占用的字节数位 %d ", n2, unsafe.Sizeof(n2))
}
2.2.2 浮点型、小数
浮点数=符号位+指数位+尾数位说明:浮点数都是有符号的.
- float64比float32精度更高
package main
import (
"fmt"
_ "unsafe"
)
func main(){
var n1 float32 = 12.830183430183430183555577552278
//结果:n1= 12.830183,精度损失
fmt.Println("n1=", n1)
}
浮点数使用细节:
- Golang 浮点类型有固定的范围和字段长度,不受具体 OS(操作系统)的影响
- Golang的浮点数默认是float64【开发中一般使用float64】
package main
import (
"fmt"
_ "unsafe"
)
func main(){
var num = 6.8
fmt.Printf("num的类型是 %T ", num)
fmt.Println("num=", num)
//num的类型是 float64 num= 6.8
}
2.2.3 字符型
Go中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存
- 字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。
传统的字符串是由字符组成的,Go的字符串则是由字节组成的
。- Go统一使用了UTF-8编码,因此避免了乱码的情况
- Go语言使用的是UTF8编码,3) 如 果 想 查 询 字 符 对 应 的 utf8 码 值:
http://www.mytju.com/classcode/tools/encode_utf8.asp- 英文字母-1 个字节 汉字-3 个字节
- 在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
- 可以直接给某个变量赋一个数字,然后按格式化输出时
%c
,会输出该数字对应的 unicode 字符
package main
import (
"fmt"
_ "unsafe"
)
func main(){
var c1 int = 'a'
var c2 int64 = '中'
fmt.Println("c1=", c1, " c2=", c2)
fmt.Printf("c1=%c, c2=%c", c1, c2)
//结果:
// c1= 97 c2= 20013
// c1=a, c2=中
}
- 字符型 存储到 计算机中,需要将字符对应的码值(整数)找出来存储:
字符—>对应码值 >二进制–>存储
读取:二进制----> 码值 ----> 字符 --> 读取
2.3.4 布尔型
- 布尔类型,也叫:bool,只允许取
true或者false
- 占1个字节
- 适用于逻辑运算
2.3.5 基本数据类型相互转换
Golang 和 java / c 不同,Go 在不同类型的变量之间赋值时需要显式转换。也就是说 Golang 中数据类型不能自动转换。【因此,等号两边得数值需要是同一类型】
- 表达式 T(v) 将值 v 转换为类型 T
T: 就是数据类型,比如 int32,int64,float32 等等
v: 就是需要转换的变量- 在转换中,比如将 int64 转成 int8 【-128—127】 ,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。 因此在转换时,需要考虑范围.
package main
import (
"fmt"
_ "unsafe"
)
func main(){
var num1 int64 = 897382715
var num2 int8 = int8(num1)
//num2=59
fmt.Printf("num2=%v", num2)
}
2.3.6 基本数据类型与string转换
①fmt.Sprintf(“%参数”, 表达式)
更加灵活,推荐使用
package main
import (
"fmt"
_ "unsafe"
)
func main(){
var num1 int = 20
var str string
str = fmt.Sprintf("%d", num1)
//str type of string str="20"
fmt.Printf("str type of %T str=%q", str, str)
}
②使用strconv
- strconv.FormatXXX
- strconv.Itoa
package main
import (
"fmt"
_ "unsafe"
"strconv"
)
func main(){
var num1 int = 20
var str string
//①strconv.FormatXXX
str = strconv.FormatInt(int64(num1), 10)
// str type of string, str="20"
fmt.Printf("str type of %T, str=%q \n", str, str)
//②strconv.Itoa
var num2 int64 = 4135
var str2 string = strconv.Itoa(int(num2))
//str type of string , str="4135"
fmt.Printf("str type of %T , str=%q", str2, str2)
}
2.3.7 string转基本数据类型
使用strconv包中得函数
注意:
package main
import (
"fmt"
_ "unsafe"
"strconv"
)
func main(){
var str string = "true"
var b bool
b , _ = strconv.ParseBool(str)
//b type bool b=true
fmt.Printf("b type %T b=%v\n", b, b)
}
注意:
在将 String 类型转成 基本数据类型时,要确保 String 类型能够转成有效的数据,比如 我们可以把 “123” , 转成一个整数,但是不能把 “hello” 转成一个整数,如果这样做,Golang 直接将其转成 0 , 其它类型也是一样的道理. float => 0 bool => false
package main
import (
"fmt"
_ "unsafe"
"strconv"
)
func main(){
var str4 string = "hello"
var n3 int64 = 11
//讲str4以十进制的形式转成int64
n3, _ = strconv.ParseInt(str4, 10, 64)
//n3之前是11,str4是字符串; 如果没有转成功,就返回0,因此n3被更新为0
fmt.Printf("n3 type %T n3=%v\n", n3, n3)
}
2.3 指针
2.3.1 基本概念
- 基本数据类型,变量存的就是值,也叫值类型
- 获取变量的地址,用&,比如: var num int, 获取 num 的地址:&num 分析一下基本数据类型在内存的布局
- 指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值
比如:var ptr *int = &num
举例说明:指针在内存中的布局
- 获取指针类型所指向的值,使用:*,比如:var ptr int, 使用ptr 获取 ptr 指向的值
- 案例:
- 写一个程序,获取一个 int 变量 num 的地址,并显示到终端
- 将 num 的地址赋给指针 ptr , 并通过 ptr 去修改 num 的值
package main
import (
"fmt"
_ "unsafe"
_ "strconv"
)
func main(){
var num int = 43
var ptr *int = &num
*ptr = 20
//num=20
fmt.Printf("num=%d", num)
}
2.3.2 注意事项[值类型和引用类型]
①概念
- 值类型,都有对应的指针类型, 形式为 *数据类型,比如 int 的对应的指针就是 *int, float32
对应的指针类型就是 *float32, 依次类推。- 值类型包括:基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
- 值类型:基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
- 引用类型:指针、slice 切片、map、管道 chan、interface 等都是引用类型
②特点
值类型:变量直接存储值,内存通常在栈中分配
引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收
- 内存的栈区和堆区示意图:
2.4 标识符
- Golang 对各种变量、方法、函数等命名时使用的字符序列称为标识符
- 凡是自己可以起名字的地方都叫标识符
2.4.1 标识符命名规则
- 由 26 个英文字母大小写,0-9 ,_ 组成
- 数字不可以开头。var num int //ok var 3num int //error
- Golang 中严格区分大小写。
var num int var Num int
说明:在 golang 中,num 和 Num 是两个不同的变量- 标识符不能包含空格
- 下划线"_"本身在 Go 中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用
- 不能以系统保留关键字作为标识符(一共有 25 个),比如 break,if 等等…
但是预定义标识符,如:int
等,可以作为变量名【强烈不推荐!!!!】
2.4.2 注意事项
- 包名:保持 package 的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库不要冲突 fmt
- 变量名、函数名、常量名:采用驼峰法
举例:
var stuName string = “tom” 形式: xxxYyyyyZzzz …
- 如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用 ( 注:可以简单的理解成,首字母大写是公开的,首字母小写是私有的) ,在 golang 没有public , private 等关键字。
2.4.3 系统保留关键字与预定义标识符
- 系统保留关键字
- 系统预定义标识符
2.5 运算符
2.5.1 算数运算符使用【/、++、–、%】
①除号使用:/
②++、–使用:
- Golang 的++ 和 – 只能写在变量的后面,不能写在变量的前面,即:只有 a++ a-- 没有 ++a
–a- Golang 的设计者去掉 c / java 中的 自增自减的容易混淆的写法,让 Golang 更加简洁,统一。(强制性的)
③求余符号使用:%
- 对于除号 “/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。 例如: x := 19/5 ,结果是 3
- 当对一个数取模时,可以等价 a%b=a-a/b*b , 这样我们可以看到 取模的一个本质运算。
package main
import (
"fmt"
_ "unsafe"
_ "strconv"
_ "go_code/project01/main/model"
)
func main(){
//求余符号:%, 可以理解为符号不用看,最后结果与分母符号(如:10)一致
fmt.Println("10 % 3 = ", 10 % 3)
fmt.Println("-10 % 3 = ", -10 % 3)
fmt.Println("10 % -3 = ", 10 % -3)
fmt.Println("-10 % -3 = ", -10 % -3)
// 10 % 3 = 1
// -10 % 3 = -1
// 10 % -3 = 1
// -10 % -3 = -1
}
课堂练习:
2.6 进制
2.6.1 进制表示
二进制:0,1;满2进1
十进制:0-9,满10进1
八进制:0-7,以数字0开头表示,如:0726
十六进制:0-9及A-F,满16进1,以0x或0X开头,此处的A-F不区分大小写
2.6.2 进制转换
①二进制转其他进制:
- 2转8:
- 2转10:
每一位从2的0次方,2的一次方开始,如:012= 2*2^0+1*2^1+0*2^2- 2转16:
②其他进制转二进制:
- 8转2、10转2、16转2:
一直除2,然后余数从下至上排列
2.6.3 原码、补码、反码
分别是”按位与&、按位或|、按位异或^,它们的运算规则是:
- 按位与& : 两位全为1,结果为 1,否则为 0
- 按位或| : 两位有一个为 1,结果为 1,否则为 0
- 按位异或 ^ : 两位一个为 0,一个为 1,结果为 1,否则为 0
注意事项
- Go语言中没有++a或- -a,
- Golang 的自增自减只能独立使用,不能直接后接赋值
//错误写法
a = i++
//正确写法
i++
a = i
面试题
①不使用中间变量,交换a、b的值
package main
import (
"fmt"
_ "unsafe"
_ "strconv"
_ "go_code/project01/main/model"
)
func main(){
var a int = 9
var b int = 13
a = a + b
b = a - b // a
a = a - b
fmt.Println("a===>", a) //13
fmt.Println("b===>", b) //9
}