语言特点
- 从C语言中继承了很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等等,也保留了和C语言一样的编译执行方式及弱化的指针
func testPtr(num *int){ *num = 20 }
- 引入包的概念,用于组织程序结构,Go语言的一个文件都要归属于一个包,而不能单独存在。
package main//一个go文件需要在一个包
- 垃圾回收机制,内存自动回收,不需开发人员管理
- 天然并发(重要)
-
从语言层面支持并发,实现简单
-
goroutine,轻量级线程,可实现大并发处理,高校利用多核。
相较进程和线程而言,协程的上下文切换则快了很多, 它只需在【用户态】即可完成上下文的切换,并且需要切换的上下文信息也较少
-
基于CPS并发模型(Communicating Sequential Processes)实现
-
- 吸收了管道通信极值,形成Go语言特有的管道channel,通过管道channel,可以实现不同的goroutine之间的通信
- 函数可以返回多个值。
func getSumAndSub(n1 int, n2 int)(int,int){ sum := n1 + n2 sub := n1 - n2 return sum , sub }
- 新的创新:比如切片slice、延时执行defer等
变量
var i int
定义int型变量i
i=10
定义
fmt.Println("i=",i)
使用
使用注意事项
- 变量使用的三种方式
- 第一种:指定变量类型,声明后若不赋值,就是用默认值
var i int fmt.Println("i=",i) //结果为0,int的默认值为0
- 根据值自行判定变量类型(类型推导)
var num = 10.11 fmt.Println("num=",num)
- 省略var,注意
:=
左侧的变量不应该是已经声明过的,否则会导致编译错误name := "tom"//等价于var name string name = "tom" fmt.Println("name=",name)
- 第一种:指定变量类型,声明后若不赋值,就是用默认值
- 多变量声明
var n1, n2, n3 int//方式1 var n1, n2, n3=100, "tom",888//方式2,n1= 100 n2= tom n3= 888 n1, n2, n3:=100, "tom",888//方式3,此方式不能声明全局变量 //原因是此语句等于两句 var n3 int + n3 = 100 //而n3 = 100这样的语句不能在函数体外执行
- 一次性声明多个全局变量
var( //局部变量也能这么声明 n1=10 n2 = 3 n3 ="bb" )
- 变量数据类型不能改变
var i int = 10 i=20 //ok i=1.3 //error
- 变量在同一个作用域内不能重名
- 默认值0,小数默认值0,字符串默认空串
变量的数据类型
类型 | 有无符号 | 占用存储空间 | 表数范围 |
---|---|---|---|
int8 | 有 | 1字节 | -128~127 |
int16 | 有 | 2字节 | -2^{15}~2^{15}-1 |
int32 | 有 | 4字节 | -2^{31}~2^{31}-1 |
int64 | 有 | 8字节 | -2^{63}~2^{63}-1 |
类型 | 有无符号 | 占用存储空间 | 表数范围 |
---|---|---|---|
uint8 | 无 | 1字节 | 0~255 |
uint16 | 无 | 2字节 | 0~2^{16}-1 |
uint32 | 无 | 4字节 | 0~2^{32}-1 |
uint64 | 无 | 8字节 | 0~2^{64}-1 |
类型 | 有无符号 | 占用存储空间 | 表数范围 | 备注 |
---|---|---|---|---|
int | 有 | 32位4字节 64位8字节 | -2^{31}~2^{31}-1 -2^{63}~2^{63}-1 | |
uint | 无 | 32位4字节 64位8字节 | 0~2^{32}-1 0~2^{64}-1 | |
rune | 有 | 与int32一样 | -2^{31}~2^{31}-1 | 表示中文字符 unicode码 |
byte | 无 | 与unit8等价 | 0~255 | 当要存储字符时 选用byte |
整型的使用细节
- Golang的整型默认声明为int型
- 查看变量数据类型
fmt.Printf("n1的类型%T",n1)
- 查看变量数据大小
fmt.Printf("n1占用的字节数是%d",n1,unsafe.Sizeof(n1))
- 在保证程序正确运行下,尽量使用占用空间小的数据类型
小数
类型 | 占用存储空间 | 表数范围 |
---|---|---|
单精度float32 | 4字节 | -3.403E38~3.403E38 |
双精度float64 | 8字节 | -1.798E308~1.798E308 |
-
浮点数都是有符号位的。浮点数=符号位+指数位+尾数位
-
尾数部分可能丢失,造成精度损失。
-
Golang的浮点类型默认是float64
字符类型
Go中没有专门的字符类型,一般用byte保存
传统的字符串是由字符组成的,而Go的字符串是由字节组成的
输出:
var c1 byte = 'a'
fmt.Printf("c1=%c",c1)//需要按照字符的方式输出时需要格式化输出fmt.Printf 和%c
注意:
-
Go语言的字符使用UTF-8编码,英文字母1个字节,汉字3个字节
-
在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码码值
-
可以直接给某个变量赋一个整数,然后按格式化输出的%c,输出对应的unicode(UTF-8编码)字符
-
字符类型可运算,相当于整数
布尔类型
-
只允许取值true和false,不能存其他整数
-
占1个字节
字符串类型
-
字符串一旦赋值了,字符串就不能修改了,在Go中字符串是不可变的
-
字符串的两种形式
-
双引号,会识别转义字符
-
反引号(`),以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
var str1 string = "abc\ncba" fmt.Println(str1) var str2 string =`package main import ( "fmt" //引入一个包 fmt ) ` fmt.Println(str2)
-
- 字符串的拼接方式
var str1 string = "hello " str2 := "world\n" str2+="haha" fmt.Println(str1+str2)
- 当拼接太长要分行是,需要在行后留"+"(因为默认+";",有"+"后就不会加了)
var str3 string ="hi" + "my" +"name"+"is"+ "limei" fmt.Println(str3)
基本数据类型的默认值
var a int //0
var b float32 //0
var isNum bool //false
var name string// ""
基本数据类型的转换
主要区别
只能显示转换,不能自动转换,不管是从高精度到低精度,还是从低精度到高精度
基本语法
var i float64 = 100.00000874
var j = float32(i)
fmt.Println(j)
var n1 int32 =932
var n2 int64 = int64(n1)
fmt.Println(n2)
细节说明
-
被转换的是变量存储的数据,变量本身的数据类型没有变化(说白了只是传值)
-
从大到小转换编译不会报错,但是转换的结果按照溢出处理(应该是直接按位转换)
var n1 int32 = 12
var n3 int8
var n4 int8
n3 = int8(n1) + 127//编译通过,但是会溢出
n4 = int8(n1) + 128//编译不通过,因为128放不进去
基本数据类型和string的转换
方法1:fmt.Sprintf("%参数",表达式)
【推荐】
var num1 int = 99
var num2 float64= 23.456
var b bool = true
var myChar byte= 'h'
var str string
str=fmt.Sprintf("%d",num1)
fmt.Printf("str type is %T str=%q\n",str,str)//%q结果加""
str=fmt.Sprintf("%.2f",num2) //四射五入保留到小数点后2位
fmt.Printf("str type is %T str=%q\n",str,str)
str=fmt.Sprintf("%t",b)
fmt.Printf("str type is %T str=%q\n",str,str)
str=fmt.Sprintf("%c",myChar)
fmt.Printf("str type is %T str=%q\n",str,str)
方法2:strconv包(实现了基本数据类型和其字符串表示的相互转换)
import "strconv"
var num1 int =99
var num2 float64= 23.456
var b bool = true
var str string
str=strconv.FormatInt(int64(num1),10)//10代表转成十进制,且int需要是64位
fmt.Printf("str type is %T str=%q\n",str,str)
str=strconv.FormatFloat(num2 , 'f',10,64)//'f'表示输出格式,10表示小数位后保留10位,64表示小数是float64
fmt.Printf("str type is %T str=%q\n",str,str)
str=strconv.FormatBool(b)
fmt.Printf("str type is %T str=%q\n",str,str)
方法3:strconv包中的函数Itoa
(int64要转换)
var num5 int = 4567; //int64
str := strconv.Itoa(num5)//int(num5)
fmt.Printf("str type is %T str=%q\n",str,str)
string转基本数据类型
var str string = "true"
var b bool
b , _= strconv.ParseBool(str)//ParseBool 返回两个值,第一个为bool,第二个为error。必须接收但可以用“_”忽略
var str2 string = "127"
var n1 int64
n1 , _= strconv.ParseInt(str2,10,64)//返回的是64位,所以必须用64位接收,但是ParseInt的参数可以是32或更小,精度会不同
var str3 string = "127.0020"
var f1 float64
f1 , _= strconv.ParseFloat(str3,64)//同上
注意:在将string类型转成基本数据类型时,要确保string类型能够转成有效的数据。如果不能,Golang直接将其转成0。bool默认为false
指针
var i int =10
var p *int = &i
值类型和引用类型
-
值类型:基本数据类型int系列,float,bool,string;数组和结构体struct
-
引用类型:指针,slice切片,map,管道chan,interface等
区别:
值类型通常分配在栈上(存的是值)
引用类型通常分配在堆上(存的是地址,地址指向堆区)
标识符命名规则
所有可以命名的都是标识符
基本规则
-
由26个字母大小写,0-9,_ 组成
-
不能数字开头
-
严格区分大小写
-
不能有空格
-
“_” 本身就是特殊的标识符,不能单独使用。单独时作为占位符使用
注意事项
-
包名:保持package的名字和目录一致,尽量取简短且有意义的包名,不要和标准库冲突
-
变量、函数、常量名用驼峰法:
var stuName string
,首字母(第一个单词)小写,后面的首字母大写 -
如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用。可以简单理解成首字母大写公有,首字母小写私有。注意:Golang里没有public、private的关键字
//main package main import ( "go_code/project1/model" "fmt" ) func main(){ fmt.Println("helloName=",model.HelloName) } //pac.go package model var HelloName int = 91