Go语言程序基础
Go语言程序基础
import "fmt" //fmt包中提供格式化,输出,输入的函数。
注意事项:
①Go源文件以"go”为扩展名。
②Go应用程序的执行入口是main()函数。
③Go语言严格区分大小写。
④Go方法由一条条语句构成,每个语句后不需要分号(Go语言会在每行后自动加分号)
⑤Go编译器是一行行进行编译的,一行只能写一条语句,否则报错。
转义符:
①\t:表示一个制表符,通常使用它可以排版。
②\n:换行符
③\\:一个\
④\":一个"
⑤\r:一个回车
注释:
①行注释//
②块注释/**/,不可嵌套
缩进:
①Shift+tab:整体左移;再tab:右移;
②用gofmt进行格式化;

③运算符两边习惯性各加一个空格。
④代码风格:

⑤一行最长不超过80个字符,超过的请使用换行展示。
Golang 中文网在线标准库文档:https://studygolang.com/pkgdoc
Dos常用指令:
Dos:Disk Operating System磁盘操作系统
清屏:cls
推出dos:exit
目录操作指令:
查看目录:D:\>dir
切换到F盘:D:\>cd /d f:
切换到当前盘的其他目录下(相对路径、绝对路径):
>cd d:\test100\abc100
>cd abc100
切换到上一级:>cd ..
切换到根目录:>cd \
新建一个目录:>md ok200
新建多个目录:>md ok300 ok400
删除空目录:>rd ok100
删除目录、子目录和文件,不带询问:>rd /q/s ok200
删除目录、子目录和文件,带询问:>rd /s ok200
文件的操作:
新建或追加内容到文件:>d:\test100\abc100\abc .txt
>echo atguigu > abc2 .txt
复制文件:>copy abc .txt d:\test200 使用原来文件名
>copy abc .txt d:\test200\ok.txt 重写指定名
移动文件:>move abc-txt f:\
删除指定文件:>del abc2.txt
删除所有文件:>del *.txt
变量:
①变量表示内存中的一个存储区域
②该区域有自己的名称(变量名)和类型(数据类型)

Golang变量使用的三种方式
①Golang的变量如果没有赋初值,编译器会使用默认值:
int默认值0 ;string默认值为空串;小数默认为0。
②根据值自行判定变量类型(类型推导):var num = 10.11
③省略var,注意:=左侧的变量不应该是已经声明过的,否则会导致编译错误:
name := “tom” 等价于var name string name = "tom"
④多变量声明:
var n1,n2,n3 int
var n1,name, n3 = 100,"tom”,888
n1,name , n3 := 18e,"tom",888
一次性声明多个全局变量:
var (
n3 = 300
n4 =900
name2 = "mary"
)
⑤该区域的数据值可以在同一类型范围内不断变化(重点)
⑥变量在同一个作用域(在一个函数或者在代码块)内不能重名
⑦变量=变量名+值+数据类型,变量的三要素

数据类型:



整数型:
①分类:有符号int、无符号uint,大小和系统有关。
②默认为int型。
③如何在程序查看某个变量的字节大小和数据类型(使用较多):
var n2 int64 =10
fmt.Printf("n2的类型%T n2占用的字节数是%d ", n2, unsafe.Sizeof(n2))
④遵守保小不保大的原则。
⑤bit:计算机中的最小存储单位。Byte:计算机中基本存储单元。1byte = 8 bit

小数、浮点型:
①浮点数=符号位+指数位+尾数位,浮点数都是有符号的。
②尾数部分可能丢失,造成精度损失。
③默认为float64类型。
④表示形式:
十进制数形式:5.12 .512(必须有小数点)
科学计数法形式:5.1234e2 = 5.12*10的2次方
5.12E-2 = 5.12/10的2次方
字符型:
Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用 byte来保存。
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而Go的字符串是由字节组成的。
①字符常量是用单引号(")括起来的单个字符。
②Go中允许使用转义字符\’来将其后的字符转变为特殊字符型常量。
③Go 语言的字符使用UTF-8编码。英文字母:1个字节;汉字:3个字节
④在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值。
⑤可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的unicode字符:
var c4 int = 22269 // 22269 ->‘国’120->‘x’
fmt.Printf("c4=%c\n",c4)
⑥字符类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码。
字符型存储到计算机中,需要将字符对应的码值(整数)找出来:
存储:字符--->对应码值--->二进制--->存储
读取:二进制--->码值--->字符--->读取
布尔类型(bool类型):
①只允许取值true和false。
②占1个字节。
③适于逻辑运算,一般用于程序流程控制。
④默认为false
String类型:
Go的字符串是由单个字节连接起来的。
Go语言的字符串的字节使用UTF-8编码标识 Unicode文本。
字符串一旦赋值了,字符串就不能修改了:在Go中字符串是不可变的。
两种表示形式:
双引号:会识别转义字符
反引号:以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果。
基本数据类型的相互转换:
Go在不同类型的变量之间赋值时需要显式转换。也就是说Golang中数据类型不能自动转换。
①可从表示范围小-->表示范围大,也可从范围大--->范围小
②被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化!
var i int32 = 100
var n int64 = int64(i)
i还是int32
③int64转成int8【-128--127】,编译时不会报错,转换的结果是按溢出处理。
练习:
var n1 int32 =12
var n2 int64
var n3 int8
var n4 int8
n2 =n1+20 //int32 ---> int64错误
n3 =n1+20 //int32--->int8错误
n2 = int64(n1)+ 20 //正确
n3 = int8(n1) +20 //正确
n4 = int8(n1)+127 //编译通过,但是结果不是127+12,按溢出处理
n3 = int8(n1)+128 //编译不过,编译器认为int8最大128,怎么还能加128呢?
基本数据类型和string的转换
基本数据类型 → string:
①fmt.Sprintf("%参数",表达式) [常用、灵活]
func Sprintf(format string,a ...interface{})string
Sprintf根据format参数生成格式化的字符串并返回该字符串。
var numi int =99
var num2 float64 =23.456
var b bool =true
var mychar byte = 'h'
var str string //空的str
str = fmt.Sprintf("%d" , num1)
str = fmt.Sprintf("%f"", num2)
str = fmt.Sprintf("t", b)
str = fmt.Sprintf(%c", mychar)
②使用strconv包的函数:

var num3 int = 99
var num4 f1oat64 = 23.456
var b2 bool = true
str = strconv.FormatInt(int64(num3),10)
// strconv.FormatFloat(num4,'f',10,64)
//’f’:格式;10:小数位保留10位;64:这个小数是float64
str = strconv.FormatFloat(num4,"f',10,64)
str = strconv.FormatBoo1(b2)
var num5 int64 =4567
str = strconv. Itoa(int(num5))
string → 基本数据类型:
①使用strconv包的函数:

var str string = “true"
var b bool
// strconv.ParseBool(str)函数会返回两个值(value bool, err error)
//因为我只想获取到value bool,不想获取err,所以使用_忽略
b , _= strconv.ParseBool(str)
var str2 string = “1234590”
var n1 int64
var n2 int
n1 , _ = strconv.ParseInt(str2, 10, 64)
n2 = int(n1)
var str3 string = "123.456"
var f1 float64
f1 , _= strconv.ParseFloat(str3,64)
指针:
①获取地址&
②指针变量存的是一个地址,这个地址指向的空间存的才是值:var ptr *int = &num
引用:
①值类型:变量直接存储值,内存通常在栈中分配
②引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收。
标识符:
①由26个英文字母大小写,0-9 ,_组成
②数字不可以开头。
③严格区分大小写。说明:在golang 中,num和 Num是两个不同的变量
④标识符不能包含空格。
⑤下划线"_"在Go中称为空标识符。可以代表任何其它的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用。
⑥不能以系统保留关键字作为标识符(一共有25个),比如 break,if等等..
①包名:保持package 的名字和目录保持一致,简短,有意义,不要和标准库不要冲突。
②变量名、函数名、常量名:采用驼峰法:xxxYyyyyZzzz...
③如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;
如果首字母小写,则只能在本包中使用(首字母大写是公开的,首字母小写是私有的),在golang没有public,private 等关键字。


运算符:
①算术运算符

Golang的++和--只能写在变量的后面:没有++i、--i
Golang 的自增自减只能当做一个独立语言使用,不能这样使用:if i++>0;i=i++
②赋值运算符


③比较运算符/关系运算符

④逻辑运算符

⑤位运算符

⑥其它运算符

优先级:

Go语言明确不支持三元运算符。
键盘输入:
①导入fmt包
②调用fmt包的fmt.Scanln()或者fmt.Scanf():
fmt.Scanf("%s %d %f %t",&name, &age,&sa1, &isPass)
进制:
①二进制。在golang中,不能直接使用二进制来表示一个整数,它沿用了c的特点。
②十进制。
③八进制。以数字0开头表示。
④十六进制:0-9,A-F。以Ox或OX开头表示。【A-F不区分大小写】

转十进制:



二→八:每三位转
二→十六:每四位转
八→二:一位数转三位
十六→二:一位数转四位
原码、反码、补码:
①二进制的最高位是符号位:0表示正数,1表示负数:1 ===>[0000 0001]; -1===>[1000 0001]
②正数的原码,反码,补码都一样
③负数的反码 = 它的原码符号位不变,其它位取反(0->1,1->0)
④负数的补码 = 它的反码+1
⑤0的反码,补码都是0
⑥在计算机运算的时候,都是以补码的方式来运算的:1-1=1+(-1)
按位与&;按位或|;按位异或^
计算 -2^2:
-2的原码1000 0010 → 反码1111 1101 → 补码1111 1110
2的补码 0000 0010
得11111100 (补码) →原码
补码1111 1100 → 反码1111 1011 → 原码1000 0100 == - 4
右移运算符>>:低位溢出,符号位不变,并用符号位补溢出的高位
左移运算符<<:符号位不变,低位补0
If条件表达式:嵌套分支不宜过多,建议控制在3层内。
Switch分支控制:匹配项后面也不需要再加break。
①default语句不是必须的.
②switch后也可以不带表达式,类似if --else分支来使用。
③switch 后也可以直接声明/定义一个变量,分号结束,不推荐。
switch grade := 90; {
case grade > 90 :…
④switch穿透:如果在case语句块后增加fallthrough,则会继续执行下一个case。
⑤switch语句还可以被用于type-switch来判断某个interface变量中实际指向的变量类型。
var x interface{}
var y =10.0
x = y
switch i :=x.(type){
case nil:
fmt.Printf("x的类型~:%T", i )
for循环:
A. for i := 1; i<10; i++ {…}
B. j:=1 for j<10{…}
C. j:=1 for { if j<10{…}…}
D. for {…}。等价for ; ;是一个无限循环,通常需要配合break语句使用
Golang提供for-range的方式,可以方便遍历字符串和数组。
传统的字符串遍历:
var str string ="hello,wor1d!"
for i:=0; i< len(str); i++{
fmt.Printf("%c \n",str[i])
} //使用到下标...
for-range:
str = "abc~ok"
for index, val := range str {
fmt.Printf("index=%d,val=%c \n", index,val)
}
如果字符串含有中文,则传统的遍历字符串方式,就是错误,会出现乱码。原因是传统的对字符串的遍历是按照字节来遍历,而一个汉字在utf8编码是对应3个字节。
解决办法:
①需要要将str转成rune切片
var str string ="hello,wor1d!北京"
str2 := []rune(str)
for i :=0; i<len(str2); i++ {
fmt.Printf("%c \n", str2[i]) //使用到下标...
}
②for-range是按照字符方式遍历。字符串有中文,也是ok。
str = "abc~ok上海”
for index,val :=range str {
fmt.Printf("index=%d,val=%c \n", index, val)
}
Go语言没有while和 do...while语法
多重循环控制(重点,难点)
①嵌套循环:在外边的 for称为外层循环在里面的 for循环称为内层循环。【建议一般使用两层,最多不要超过3层】
②只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。
③外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。
随机生成1-100整数:
//time.Now().Unix():返回一个从 1970 1-1 0:0:0 到现在的一个秒数rand.Seed(time.Now().Unix())
fmt.Println("n", rand.Intn(100)+1)
跳转控制语句:break、continue、goto、return
continue:
①用于结束本次循环,继续执行下一次循环。
②出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环。
goto:
①可以无条件地转移到程序中指定的行。
②通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能。
③在Go程序设计中一般不主张使用goto语句,以免造成程序流程的混乱。
var n int = 30
fmt.Print1n("ok1")
if n> 20 {
goto label1
}
fmt.Print1n("ok2")
label1:
fmt.Println("ok5")
包:
go的每一个文件都是属于一个包的,go是以包的形式来管理文件和项目目录结构的。
作用:
区分相同名字的函数、变量等标识符
当程序文件很多时,可以很好的管理项目
控制函数、变量等访问范围,即作用域
相关说明:
打包:package包名
引入:import "包的路径"
import (
"包名"
"包名"
)
被调用的类的类名首字母要大写,相当于public
调用函数:包名.函数名( )
如果包名较长,Go支持给包取别名:取别名后,原来的包名就不能使用了
import(
util "go_code/chaptere6/fundemoo1/utils"
)
import包时,路径从$GOPATH的src下开始,不用带src,编译器会自动从src下开始引入。
文件的包名通常和文件所在的文件夹名一致,一般为小写字母。