Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。
Go语言的基本语句:
package main //声明main包
import "fmt" //导入fmt包
func main(){ //创建主函数
fmt.Println("Hello go") //调用fmt包中的打印函数
}
需要注意的是:
Go程序是通过package来组织的,区别于java语言程序以类来组织程序。同时,每个文件必须先声明包,程序必须有一个package main,只有package 名称为main的包可以包含main函数,一个可执行程序有且仅有一个main包 ,即Go语言程序中存在且仅存在一个入口函数main函数,类似于java语言程序公共类里面的main方法。其中,Go语言对于函数的左大括号‘{’具有严格的要求:{不可以独占新行,相应代码末尾也无需添加分号。
func main(){
}
在主函数中调用其他函数时,大部分的函数都需要导入包,才能完成相应的功能。但不同于其他语言,在Go语言的程序中,如果使用import导入包之后,一定要使用包内函数,否则就会报错。同理,若在程序中声明了量,那也必须要使用,否则就会报错,这也是Go语言比较不人性化的一点。
import “fmt”
存在于“fmt”当中的Println()函数则是能够自动换行的打印函数。
fmt.Println("Hello go")
Go语言注释方式与其他语言相似:
//为单行注释
/*
这样的注释块可一次性注释多行
*/
关于Go语言程序的运行:
Go语言中大部分的编译代码都在命令指令行中输入,例如:
我们使用Liteide时,一个Go工程之中只能有一个main函数,此时的解决方法有二:
1.一个Go工程会在一个文件夹之中,我们可以将新程序放入另一个文件夹中,但此方法较为繁琐。
2..我们可以再命令指令行中执行文件:
通过go build name.go可以编译name.go文件中的代码,生成一个name.exe可执行文件,运行可执行文件。
我们也可以通过go run name.go在不生成明显程序的情况下直接编译运行(推荐)。
Go语言中的基本数据类型:
为方便管理并且分配内存空间需明确数据类型:
为Go语言中的量命名时有一定的规范:
1.量的名称只由字母,下划线,数字组成
2.量的名称不能以数字开头
3.量的名称不能与Go语言相关关键字重名
4.量在命名时需区分大小写
Go语言中的关键字有25个,只能在特定结构中使用:
此外还有大约30多个预定义名字:
Go语言中的量-以整型为例:
变量:顾名思义,就是在程序运行期间可以改变的量,我们可以通过以下语法来声明变量:
变量的声明:
格式:关键字(var) 变量名称 数据类型
var name int //用来定义一个整型变量name
var name0, name1 int //用来定义两个个整型变量name0与name1
要注意:
声明但没有初始化的整型变量会被默认赋初始值0。
同一个大括号里面的变量名是唯一的,不可以同名,也不可以重复定义。
变量的赋值:为变量赋值前必须先声明变量,变量可以多次被赋值以达到修改变量的值得目的。若在程序中声明了量,那也必须要使用,否则就会报错。
name=20 //将变量name的值赋为20
name0,name1 = 30,40 //将变量name0,name1分别赋值为30,40
显然,在定义变量之后再为变量赋值有些繁琐,我们可以通过其他的方式在定义的同时为变量初始化,声明并初始化的过程等同于先声明变量再为变量赋值。
var name int = 10 //初始化变量name
var name0, name1 int = 30, 40 //用来定义两个整型变量name0与name1
同时,我们也可以使用变量的自动推导类型:必须初始化,通过初始化的值来确定数据类型。此方法较为常用并且较为简便,等同于先声明后赋值,同样不可以同名,不可以重复定义。
name:=10 //自动推导类型赋值
name0, name1 := 30, 40 //自动推导类型赋值,多重赋值
var name2 = 50
这时有必要提及Go语言中对两个变量值的互换上的代码优化:
我们使用的传统方法:
package main
import "fmt"
func main(){
var num0, num1 int = 10,20
var tmp int
fmt.Println(num0,num1,tmp)
//开始交换num0,num1的值
tmp=num0
num0=num1
num1=tmp
fmt.Println(num0,num1,tmp)
}
在Go语言中,通过自动推导类型,我们这可以写出如下等效代码:
package main
import "fmt"
func main(){
num0, num1 := 10, 20
fmt.Println(num0,num1)
//开始交换num0,num1的值
num0, num1 =num1, num0
fmt.Println(num0,num1)
}
匿名变量:
package main
import "fmt"
func main(){
var tmp int
num0, num1 := 10, 20
tmp, _ = num0,num1 //下划线代表了当前位置变量的缺省
fmt.Println(num0,num1,tmp)
}
通过如上操作之后,将变量位置用下环线代替,num1的值将不会在赋值语句中被使用,但_匿名变量配合函数返回值使用更加具有优势。
package main
import "fmt"
func test()(a,b,c int){
return 1,2,3
}
func main(){
num0, num1 := 10, 20
num0,_,num1=test()
fmt.Println(num0,num1)
}
此时,暂时不需要的部分将会在赋值语句中被缺省。
常量:与变量相反,则是程序运行期间无法改变的量,一般可以再不需要修改的核心数据声明时使用。
const pi float64=3.14159265
这样声明之后,如果在后面的程序中尝试修改pi这个值,则会报错。
常量的自动推导类型:
const pi=3.1415926
需要注意的是:在常量的自动推导类型中,运算符用的是“=”而非“:=”,这是与变量自动推导类型需要区分的。
枚举:iota
1.常量自动生成器,每隔一行自动累加1,同一行的赋值是一样的
2.只能为常量赋值使用
3.iota遇到const重置为0
4.可以只写一个iota,下面的常量会自动进行赋值
func main(){
const(a,b=iota,iota //a,b均为0
c=iota //c为1
)
const d = iota //d为0
const(e=iota //e=0
f //f=1
g //g=2
)
}
我们在Go语言中常用的基本数据类型有:
整型:int, uint(无符号整型)
实型:float32, float64
复数型:complex32, complex64
字符型:byte
字符串型:string
下面正式开始介绍整型意外的基本数据类型:
布尔类型:bool
var a bool //bool类型的声明
var b=false //bool类型的自动推导
c:=true //bool类型的自动推导
要注意的是:在Go语言中,bool类型与int类型不兼容。bool类型只有两种值:真true, 假false。
浮点型:float32
var a float32 //float32类型的声明
var b=3.14 //float32类型的自动推导
c:=3.14 //float32类型的自动推导
需要注意的是:在自动推导类型当中,浮点型的数据类型变为了float64,它比float32要更加大,更加精准。
字符型(ASCII):byte
package main
import "fmt"
func main(){
ch:='a'
fmt.Println(ch) //使用基本打印函数输出ch
}
需要注意的是:使用基本打印函数打印输出ch时,输出的是97而不是a,而97就是a的ASCII码值。也就是说,在没有明确要求的情况下,字符型输出会打印出此字符对应的ASCII码值,这也证明了在Go语言中,字符型与整形是相互兼容的。如何解决此问题:我们需要用到格式化输出方法Printf()(将会在下文详细描述)。通过对比ASCII表,我们可以发现,在Go语言中类似其他语言,对英文字符大小写的转换我们可以通过加减32的方式来完成(小写字符ASCII值大于相应大写字符ASCII值 )。ASCII码表中转义字符不可见,无法打印(‘\’转义符号‘ \n’转义字符--换行)。
字符串形:string
package main
import "fmt"
func main(){
str:="hello"
fmt.Println(len(str)) //求取字符串长度
}
內建函数:len() 输出字符串长度。
字符与字符串的区别:
1.赋值时字符用‘’ 字符串用“”
2.字符在赋值时只能输入一个字符(转移符除外)
3.字符串由一到多个字符所组成,字符串的结尾隐藏了“\0”结束字符,此字符不计入到长度中
4.字符串亦可以看做字符数组,下标从0开始 str[x]可以对相应下标的字符进行操作
复数型:complex64
package main
import "fmt"
func main(){
t:=12+3.14i //复数自动推导
fmt.Println(real(t),imag(t)) //分别输出实虚部
}
需要注意的是:自动推导类型中,复述的类型为complex128.
內建函数:real()求实部,imag()求虚部。
Go语言的输出:这些输出函数都包含在fmt包中
Print() 基本输出函数
Println() 基本输出函数,自动换行
Printf() 格式化输出:格式化输出 把变量的内容放到占位处(%d)“\n”是换行符 在控制格式有自己的优势,更容易处理多个变量。
我们在格式化输出时,常用的占位符有:
%d整形占位符
%c字符型占位符,课在上文中解决输出ASCII码问题,用%v也会出现整形输出的情况
package main
import "fmt"
func main(){
ch:='a'
fmt.Printf("%c",ch) //使用格式化打印函数输出ch
}
%s字符串类型占位符
%f浮点型占位符,出现补0情况,可用%v优化
%t布尔类型占位符,由于整型与布尔类型不兼容,所以不能用%d代替
%T读取变量数据类型
%v自动匹配格式输出
输入:阻塞程序等待用户输入
fmt.Scanf(“%d”,&num)
fmt.Scan(&num)
需要注意的是:在输入语法中,量的前面需要加上取地址符&。
不同类型变量的多重声明和赋值:
var ( //不同类型多重声明
a int
b float64
)
a,b=10,3.14 //不同类型多重赋值
同时,我们也可以为其进行初始化:
const(
a int = 10
b float64 = 3.14
)
也可以运用自动推导类型:
const(
i = 10
j = 3.14
)
var (
a = 10
b = 3.14
)
类型的转换:
1.布尔类型与整型无法兼容,不能互相转换。
2.字节型与整型可以相互转换。
var ch=‘x’
var num int
num=int(ch) //强制转换
var ch0 byte
var num0=100
ch0=byte(num0) //强制转换
别名:
我们可以再Go语言程序中为关键字写一些别名
package main
import sysout "fmt" //为包fmt起别名sysout
func main(){
type lon int64 //为量int64起别名lon
var num lon = 123456
sysout.Println(num)
}
也可以多重别名:
type (
lon int64
char byte
)
Go语言中的运算符:
算数运算符:
需要注意的是:Go语言不同于C++,运算符++与--在Go语言中之后后置没有前置。
关系运算符:
需要注意的是:关系运算符不可以范围连写,如11<=x<=13。
逻辑运算符:
需要注意的是: 逻辑运算符往往配合关系运算符使用,非0就是真,0就是假 ,但bool与int不兼容。如:a>b||c<d。非则是对布尔类型取反。与则需要前后条件均真才会返回真,其他为假,其中如果第一个条件为假,第二个条件将不会被判断和运算。非则需要前后条件全假才会返回假,其他为真,其中如果第一个条件为真,第二个条件将不会被判断和运算。
位运算符:不做详解
赋值运算符:
需要注意的是:与其他语言相相同,存在+=,-=类似的运算符,例如:a=a+b可以写为a+=b。
其他运算符:不做详解,多用于指针。
运算符优先级:
需要注意的是:优先级越大,越先运算,同运算优先级采取从左到右的顺序运算。()可以改变运算的优先级,优先算()内部。
Go语言语法部分:顺序结构,选择结构,循环结构。
顺序结构:顾名思义,按从上到下顺序执行,不做详解。
选择结构:if,switch
if语句:基础格式: if 条件 {}
条件成立,即可执行if内的语句。
package main
import "fmt"
func main(){
var num int = 5
if num==5{
fmt.Println("可运行")
}
}
if也支持一个初始化语句,初始化语句和判断条件以分号相隔:
package main
import "fmt"
func main(){
if num:=5;num==5{
fmt.Println("可运行")
}
}
if的多分支:if-else
package main
import "fmt"
func main(){
var num int = 5
if num==5{
fmt.Println("直接条件成立")
}else{
fmt.Println("直接条件不成立")
}
}
需要注意的是:else之后不再有条件。
if的多分支:if-else if-else
package main
import "fmt"
func main(){
var num int = 5
if num==5{
fmt.Println("直接条件成立")
}else if num > 5{
fmt.Println("直接条件不成立")
}else{ //这种情况则是num<5
fmt.Println("第二条件不成立")
}
}
对于上面的代码,我们也可以用以下代码代替:
package main
import "fmt"
func main(){
var num int = 5
if num==5{
fmt.Println("直接条件成立")
}
if num > 5{
fmt.Println("直接条件不成立")
}
if num < 5{
fmt.Println("第二条件不成立")
}
}
对比来说,前者代码执行时整个if-else if-else块中只要存在一次条件成立则不会再判断下面的条件,而后者需要多次判断条件不会跳过,在代码效率上有所降低。
注意:各条件下的语法都不能相同,否则会报错。
switch语句:
package main
import "fmt"
func main(){
var num int = 2
switch num{ //关键字后不再加条件,而是加量
case 1:fmt.Println("条件1成立")
case 2:fmt.Println("条件2成立")
case 3,4,5:fmt.Println("条件3成立")
default:fmt.Println("无符合条件")
}
}
与C++不同的是,case语句块不在需要加break(可主动写也可不写),语言默认跳出,但如果想按照不跳出调试,则需要在case块内加关键字:fallthrough。同理:各条件下的语法都不能相同,否则会报错。
switch也支持一个初始化语句,初始化语句和变量以分号相隔:
package main
import "fmt"
func main(){
switch num:=2;num{
case 1:fmt.Println("条件1成立")
case 2:fmt.Println("条件2成立")
case 3:fmt.Println("条件3成立")
default:fmt.Println("无符合条件")
}
}
switch后也可不附带条件,这时:
package main
import "fmt"
func main(){
var score int =91
switch{
case score>90:fmt.Println("成绩为优秀")
case score>80:fmt.Println("成绩为良好")
case score>70:fmt.Println("成绩为中等")
case score>=60:fmt.Println("成绩为及格")
default:fmt.Println("成绩不及格")
}
}
需要注意的是:switch后无条件,case后有对应条件,此程序需将case条件从大到小编写。
循环结构:for循环,range迭代器(Go语言中不写do-while/while)
for循环:基本格式:for 初始条件;判断条件;条件变化{}
package main
func main(){
var tot int
for i:=1; i<=100;i++{ //这时的i是局部变量
tot+=i
}
}
此程序完成了从1到100的累加。for循环执行过程:
1.由初始条件进入
2.判断条件是否为真
3.如果为真,执行循环;如果为假,跳出循环;
4.条件为真,进行条件变化
重复2,3,4步骤
range迭代器:返回两个值,下标及元素本身。更适合处理字符串类型数据
package main
import "fmt"
func main(){
var str string="hello go"
for i,data:=range str{ //i是下标(位置),data是元素本身 迭代读取元素更为简便
fmt.Printf("%d=%c \n",i,data)
}
}
如果使用for循环单独输出字符串中字符的下标和元素本身,则需要用i和str[i]来进行输出。
此处也可用匿名变量缺省,只获取单一变量:
for _,data:=range str{}
但如果全部条件缺省,则变成死循环,条件永远为真:
for {}
跳转语句:break与continue
break:可以用于跳出循环或者条件 ,一般配合if与for使用,如果嵌套多个循环则跳出最近内循环。
continue:跳过单次循环,不影响下一次循环,只能用在循环之中。
goto语句:大量程序下跳转较为复杂,不建议使用
package main
import "fmt"
func main(){
fmt.Println("输出语句1")
goto A //定义标签
fmt.Println("输出语句2")
A: //标签
fmt.Println("输出语句3")
}
如此,则跳过输出语句2。但:
1.goto可以用在任何地方,但不能夸函数使用
2.实现跳转---无条件跳转
3.定义了标签才可以使用
程序结构的拓展:
1.多个包可以用import(包名1 包名2 …)
2.type 定义结构体类型 type variable_name struct{}
3.type 定义接口类型 type variable_name interface{}
可见性规则拓展:
1.函数名首字母为小写则为private
2.函数名首字母为大写则为public
拓展:
import"time"
time.Sleep(time.second)//延时一秒
学习材料:01 go语言-02 快速入门go语言