




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第1章Go语言及编程环境Go语言简介01诞生背景诞生背景为应对新时代互联网的应用程序需要,谷歌的罗伯特·格瑞史莫(RobertGriesemer)、罗布·派克(RobPike)和肯·汤普逊(KenThompson)于2007年9月开始着手设计一种全新的编程语言——Go语言,随后IanLanceTaylor和RussCox加入该项目,新语言不仅原生支持并发多核编程、极大提升了编译速度,而且彻底摒弃了传统语言中很多复杂(并不实用)的语法。Go语言一经推出就广受欢迎,于2009年11月开放源代码,并在Linux及MacOSX平台上进行了实现,后来还追加了Windows系统下的实现。02设计哲学1.少即是多2.世界是组合的3.面向接口编程设计哲学(1)(2)(3)在编程领域也有一个所谓的“二八定律”,即:百分之八十的代码仅使用到百分之二十的语言特性。可见,单纯地增加语言特性并不能保证开发效率的提升,原因是它会增加复杂性,导致程序员更容易犯错。遵循“二八定律”正如用一个方向盘就可以控制汽车行驶,就没必要造具有多个方向盘甚至复杂方向变换系统的汽车。例如,Go语言只有for循环,而不像其他语言那样还有while、dowhile、foreach等多种循环语句,只提供一种方法做事情,把事情做到极致就好。做任何事只提供一种方法几何上的正交指两个向量垂直,现实中的正交是指多个因素的一个发生变化,不会影响其他因素。例如,Go语言中的协程、接口、类型系统之间是相互独立(正交)的,但在编程中通过组合运用这些特性,却可以极大地提升语言表现力,实现很多复杂的功能。提供正交的语言特性1.少即是多设计哲学2.世界是组合的Go语言的设计者从物质世界的构成模式得到启发,发现“组合”才是世间万物最基本最常见的关系,而过往的以“继承”为基础的面向对象语言(典型如Java),在对事物的描述上存在根本的缺陷,类和对象更适合表现孤立的单个事物,一旦涉及多个事物间的复杂交互就会出现各种问题,为此Go语言设计者提出“组合优于继承”的观点,采用组合的方式来描述对象之间的关系,更贴近真实的自然世界。Go没有像Java一样“宗教式”地完全面向对象,而是结合了面向过程、函数式设计及面向对象的优点,其语法元素与C语言有相似之处,用结构体(struct)及其强大的类型系统来构建具有自身特色的面向对象体系,通过函数、接口、类型、闭包等元素的组合,能够轻松地把大型程序的各个模块巧妙地衔接运作起来。设计哲学3.面向接口编程Go语言编程是面向接口的,采用一种Duck模型,即类型(类)不再需要显式地声明自己实现了哪个(些)接口,接口类型的判断完全交给底层语言编译器去处理,这就将接口与其实现彻底地分开,形成了一种“面向接口”的全新编程方式。程序员无须在一开始就精心设计整个系统的接口继承体系,而是先基于当下具体的某个应用需求局部设计实现一些小的接口,后续再根据需求变化和应用扩展的需要,通过已有接口的自由组合,构造出更抽象、更普适、功能更强的新接口,这使得Go程序的重构非常容易,尤其适合互联网时代应用快速迭代的开发方式。03优势特性优势特性Go的优势特性主要体现在如下几个方面。(1)Go的语法十分简洁,仅仅用了25个关键字,是所有主流编程语言中关键字最少的。(2)Go语言支持垃圾回收;内置强大的类型系统支持各种复合数据类型,如关联数组、切片、映射和列表等;内存安全,如内置数组边界检查,极大减少越界访问带来的安全隐患;还有大量的包和第三方库的支持。(3)基于类似C的结构体(struct)以组合方式构建的面向对象系统,不仅具备Java对象系统的所有功能,而且对问题域的描述和表现力更强,更贴近客观真实的世界;内置接口类型,通过接口组合形成新的接口,非侵入式的接口机制彻底解除了接口与实现的耦合,便于快速重构和迭代开发大型应用系统。(4)Go在语言级别原生支持并发,简化了并发程序设计;基于通道和协程通信的并发机制相比传统语言的线程机制效率更高,有利于充分发挥多核CPU的威力,为互联网云时代微服务开发的首选语言。第1章Go语言及编程环境Go语言安装与使用01平台与版本平台与版本Go是跨平台的编程语言,在各主流操作系统平台上都有对应的安装包,访问官网/dl/(Golang中国)可分别下载到Go在Windows、MacOSX、Linux平台上的安装包及源码,如图。02Windows平台安装Go语言1.下载Go语言编程环境2.安装Go语言编程环境Windows平台安装Go语言1.下载Go语言编程环境在图的页面上点击“MicrosoftWindows”区块的链接下载Go的安装包,得到的安装包文件名为go1.20.4.windows-amd64.msi。2.安装Go语言编程环境(1)双击下载得到的安装包文件,启动安装向导如图,单击“Next”按钮。Windows平台安装Go语言(2)在“End-UserLicenseAgreement”界面勾选“IacceptthetermsintheLicenseAgreement”接受许可条款,如图,单击“Next”按钮。Windows平台安装Go语言(3)在“DestinationFolder”界面设置Go的安装目录,这个目录是作为Go语言环境的GOROOT路径,通常默认“C:\ProgramFiles\Go”,如图,单击“Next”按钮。Windows平台安装Go语言(4)在下一个界面单击“Install”按钮开始安装,界面进度条显示安装进度,完成后单击“Finish”按钮关闭向导,结束安装。以管理员身份打开Windows命令行,输入“goversion”,出现Go的版本信息就表示安装成功,如图。03第一个Go程序1.编写Go程序2.运行Go程序第一个Go程序1.编写Go程序【实例1.1】编写第一个Go程序。打开Windows记事本,编写程序代码如下(hello.go):packagemain //(a)
import"fmt" //(b)
funcmain(){ //(c) fmt.Printf("Hello,我爱Go语言!@easybooks\n") //(d)}说明:(a)包声明语句。在所有Go源程序文件头部都要用一行“package包名”声明其代码所属的包,Go通过包来管理和组织源代码。(b)包导入语句。“import"包名"”语句导入包,通常Go程序都要像这样在开头用一条或多条import语句导入一个或多个需要引用的外部包,可以是Go语言内置标准库的包,也可以是第三方包或自定义的包。(c)入口函数。用func关键字声明定义一个函数,这里所声明的main函数是Go程序的入口函数,程序编译后由此进入开始执行。(d)“fmt.Printf("Hello,我爱Go语言!@easybooks\n")”调用标准输入/输出包的Printf函数输出字符串,要输出的字符串作为实参传入Printf函数,必须用双引号("")括起来,注意这里不能用单引号。第一个Go程序2.运行Go程序在Windows命令行下运行Go程序有两种方式。(1)gorun命令直接运行gorun命令直接编译并执行源码中的main函数。打开命令行,用cd命令进入到GOPATH目录,输入命令:gorunhello.go立即看到程序输出结果。第一个Go程序(2)gobuild命令生成可执行文件运行gobuild命令会先将源码编译为可执行(.exe)文件,然后由用户运行该文件来执行程序。在命令行GOPATH目录中执行命令:gobuildhello.go待命令执行过后,去到GOPATH目录下可以看到生成了一个hello.exe文件。运行文件hello.exe,直接输入:hello.exe输出同样的结果。以上两种方式运行Go程序的过程如图。第1章Go语言及编程环境Go语言集成开发环境01常用集成开发环境常用集成开发环境可用于Go语言编程的集成开发环境很多,比较常用的如下。(1)GolandGoland是由著名的JetBrains公司推出的一个商业IDE,它整合IntelliJ平台,提供了针对Go语言的编码辅助和大量工具集成。(2)LiteIDELiteIDE是由国内开发者做出的一款专门针对Go语言的轻量级开发环境,它基于Qt、Kate和SciTE,包含了跨平台开发及其它一些必要特性,对代码编写、自动补全和运行调试都有很好的支持,同时还包括了对源代码的抽象语法树视图和一些内置工具。(3)SublimeText这是一个跨平台的文本编辑器,支持编写非常多的编程语言代码,它通过一个叫GoSublime的插件来支持Go语言的代码补全和程序模版创建。(4)GoClipseGoClipse是一个为Eclipse添加Go语言编程功能的插件,通过gocode来实现代码补全,为初学者创造一个开发Go语言的环境,它依附于著名的Eclipse平台,可以很容易地享有Eclipse本身所具有的诸多功能。(5)VSCodeVSCode是一款由微软开发的跨平台开源代码编辑器,它使用JSON格式的配置文件进行所有功能和特性的配置,通过扩展程序为编辑器实现语法高亮、参数提示、编译、调试、文档生成等各种功能。02GoLand安装与配置1.安装2.初始启动3.项目配置GoLand安装与配置1.安装(1)GoLand下载地址/go/,单击官方主页上的“Download”按钮,转到下载页,点击页面上的“directlink”链接下载GoLand安装包。(2)双击下载得到的安装包goland-2023.1.2.exe,启动GoLand安装向导如图,单击“Next”按钮。GoLand安装与配置(3)在“ChooseInstallLocation”界面设置GoLand安装目录,单击“Next”按钮。(4)在“InstallationOptions”界面对GoLand安装选项进行配置,如图。为方便使用Go语言环境,建议选中全部选项,单击“Next”按钮。GoLand安装与配置(5)在“ChooseStartMenuFolder”界面选择(命名)要在其中创建程序快捷方式的开始菜单目录(通常保持默认的“JetBrains”),单击“Install”按钮开始安装,界面进度条显示安装进度,完成后在“CompletingGoLandSetup”界面确保选中了“Rebootnow”选项,单击“Finish”按钮关闭向导,如图,系统会自动重启,使所有的GoLand安装选项生效。GoLand安装与配置2.初始启动(1)GoLand环境支持老用户使用已有的配置,在初次启动时会弹出如图所示的对话框询问是否导入已有设置,由于笔者计算机是第一次安装GoLand,选“Donotimportsettings”,单击“OK”按钮。GoLand安装与配置(2)GoLand是商业软件,需要先激活才能使用。在如左图所示的界面上选中“ActivateGoLand”、“Activationcode”,于下方文本区粘贴获取到的激活码,单击“Activate”按钮,激活成功后,在接下来的界面单击“Continue”,出现欢迎界面如右图所示。GoLand安装与配置(3)GoLand界面默认背景是暗黑色,如果不习惯可以进行更改,操作方法是:点选欢迎界面左侧“Customize”切换至环境定制选项页,在“Colortheme”下拉列表中选择“IntelliJLight”选项,界面背景立刻变为舒适的亮白色,如左图所示。点选左侧“Projects”又切换回欢迎界面,如右图所示。
GoLand安装与配置3.项目配置(1)创建Go项目点击GoLand欢迎界面上的“NewProject”()图标按钮创建一个Go项目,出现“NewProject”界面,在“Location”栏设置项目保存路径及给项目命名。项目默认保存在操作系统当前用户的GolandProjects目录下,第一次创建项目时GoLand会自动生成这个目录,并给项目取默认名awesomeProject,如图所示。GoLand安装与配置(2)配置项目的Go环境项目的Go环境通过GOROOT与GOPATH两个环境变量来配置,之前在安装使用Go语言的时候对它们的意义已有所提及。GOROOT:Go语言本身(与所使用的开发工具无关)的安装目录,通常默认为“C:\ProgramFiles\Go”,当然在安装Go语言时也可通过向导的“DestinationFolder”界面进行更改。GOPATH:这是Go程序编译时参考的工作目录,类似于Java的工作区(Workspace),由用户自己创建或指定,笔者的是C:\Users\Administrator\go。开发时Go项目所要引用的第三方库、框架及其他独立的.go源文件都放在这个目录(及其子目录)下,以便Go编译器能够找到。GoLand安装与配置GOPATH则需要用户来设置,可以在一开始创建项目时就通过点选“NewProject”界面左侧“Go(GOPATH)”切换到另一个选项页界面上去设置GOPATH,也可以在项目创建好后于GoLand集成开发环境中选择菜单“File”→“Settings...”,打开如图1.16所示的“Settings”对话框窗口,在左侧树状导航视图中选中“Go”→“GOPATH”,在右边界面“GlobalGOPATH”栏工具条上点击“Add”()按钮添加GOPATH路径条目。03集成开发环境编写Go程序1.编写Go程序2.运行Go程序集成开发环境编写Go程序【实例1.2】在GoLand集成开发环境下编写和运行第一个Go程序。1.编写Go程序在GoLand集成开发环境下右击项目名,选择“New”→“GoFile”,弹出“NewGoFile”提示用户输入文件名,如图,这里选“Emptyfile”,输入“hello”直接回车,就在项目中创建了一个Go程序文件hello.go。集成开发环境编写Go程序GoLand自动打开hello.go文件编辑器,在其中编写Go程序代码(或将1.2.3节的程序代码复制粘贴到编辑器中)保存即可,如图。集成开发环境编写Go程序2.运行Go程序在GoLand环境左侧项目树状视图中右击hello.go文件项,弹出菜单选“Run'gobuildhello.go'”或者直接单击工具栏按钮运行程序,在开发环境底部出现子窗口显示运行结果,如图。第2章Go语言基础标
识
符01标识符及命名规范标识符及命名规范Go语言的标识符命名规范如下。(1)标识符由任意多个字符(大/小写字母A~Z/a~z)、数字(0~9)、下画线(_)组成。(2)第一个字符必须是字母或下画线。(3)区分大小写,如hello与Hello是两个不同的标识符。(4)标识符中不能含有空格及#、$、@等特殊符号。例如:_123 //合法123 //非法,不能以数字开头a123 //合法$a123 //非法,不能以特殊符号开头HelloWorld //合法HelloWorld //非法,不能含有空格Subject //合法Subject# //非法,不能含有#02关
键
字关键字Go是一门极简的语言,仅有25个关键字,它们按功能的不同大致可分为3类,见下表所示。分
类关键字功
能引导程序整体结构package声明程序所在的包import导入程序要用的外部(含第三方)包var声明变量const声明常量func声明和定义函数defer延迟执行go并发执行return函数返回值定义特殊类型type自定义类型struct定义结构interface定义接口map声明或创建映射chan创建通道(并发编程)控制程序流程if条件语句elsefor控制循环rangebreakcontinueswitch分支语句selectcasedefaultfallthroughgoto跳转语句03保
留
字保留字除关键字外,Go语言还有一些内部保留字,用于预定义内置的数据类型、函数及常量。Go共有39个保留字,分类列于表。分类保留字说
明内置数据类型int整型int8int16int32int64byte无符号整型uintuint8uint16uint32uint64uintptrfloat32浮点型float64complex64复数型complex128string字符串型runebool布尔型分类保留字说
明
error接口型内置函数make这些函数都是Go语言内置的,具有“全局可见性”,在编写程序时可直接调用,无须import导入或声明newlencapappendcopydeletepanicrecoverclosecomplexrealimagprintprintln内部常量true布尔型值falseiota连续的枚举值nil指针/引用的默认空值第2章Go语言基础变量与常量01变
量1.变量声明2.变量赋值变
量1.变量声明在Go语言中,变量的声明比较灵活,有3种方式。(1)标准方式标准方式就是以关键字var显式地声明单独的一个变量,格式为:var变量名类型例如:varnamestring //声明字符串型变量namevarsexbool //声明布尔型变量sexvarageint //声明整型变量age(2)批量方式在需要使用一组相关的多个变量的情形下,用批量方式进行声明会更加高效。此方式根据多变量类型是否相同,又有两种不同的声明形式,如下。①类型相同多变量的声明当要声明的几个变量类型都相同时,只须在标准方式的基础上扩充即可,格式变为:var变量名1,变量名2,...,变量名n类型例如:varage,weight,heightint //声明3个整型变量age、weight、height变
量②类型不同多变量的声明当要批量声明的一组相关变量的类型不同时,Go语言提供一种新方法,用关键字var搭配括号将这组变量的定义放在一起,格式为:var(
变量名1类型1
变量名2类型2 ...
变量名n类型n)例如:var( namestring //姓名 sexbool //性别 weightint //体重 heightint //身高 bmifloat32 //身体质量指数(体重÷身高²))变
量(3)简短方式这种方式不用var关键字,直接以“:=”操作符在声明变量的同时就对其进行初始化,格式为:变量名:=表达式 //声明(同时初始化)单个变量或者变量名1,变量名2,...,变量名n:=表达式1,表达式2,...,表达式n //声明多个变量(右边表达式要与左边变量名一一对应)变
量2.变量赋值(1)变量初始值凡用var关键字声明的变量,Go系统都会自动赋予其初始值,为变量类型的零值或空值,比如,string类型为空字符串,bool类型为false,int类型为0等。【实例2.1】声明并查看不同类型变量的初始值。程序代码如下(var00.go):packagemainimport"fmt"funcmain(){ varnamestring //标准方式声明字符串变量 varweight,heightint //批量方式声明同类型变量 var( sexbool ageint bmifloat32 ) //批量方式声明不同类型变量 note:="我的体态" //简短方式声明并初始化变量 //输出各变量的初始值 fmt.Println(note+"\n姓名:"+name) fmt.Println("性别:",sex) fmt.Println("年龄:",age) fmt.Println("体重:",weight) fmt.Println("身高:",height) fmt.Println("BMI指数:",bmi)}运行结果如图。变
量(2)单变量赋值给单个变量赋值的语句标准格式为:var变量名[类型]=值其中,“类型”可省略,Go编译器能够根据所赋值的数据类型自动推断出变量的类型,例如,下面这两条语句是等价的:varnamestring="周何骏" //单变量赋值varname="周何骏" //单变量赋值(省略类型)变
量(3)多变量赋值给多个变量赋值的程序代码的标准格式为:var(
变量名1[类型1]=值1
变量名2[类型2]=值2 ...
变量名n[类型n]=值n)这里各个变量的类型也是可以省略的,交给Go编译器自行推断。例如:var( namestring="周何骏" //姓名 sexbool=true //性别 weightint=60 //体重 heightint=173 //身高 bmifloat32=20.05 //身体质量指数(体重÷身高²))变
量也可以将多个变量的赋值语句写为一行,形如:var变量名1,变量名2,...,变量名n=值1,值2,...,值n各变量名与所赋的值按顺序对应列于等号的两边,中间以英文逗号(,)分隔,要注意变量与值的一一对应关系。变量类型可以相同也可以不同,编译器能自动识别。例如:varweight,height=60,173 //类型相同的多变量赋值varname,sex,age="周何骏",true,19 //类型不同的多变量赋值变
量【实例2.2】用多种不同方式给单个或多个变量赋值,并查看所赋的值。程序代码如下(var01.go):packagemainimport"fmt"funcmain(){ varname="周何骏" //单变量赋值 varweight,height=60,173 //多变量赋值(写为一行) var( sex=true age=19 bmi=20.05 ) //多变量赋值(标准格式) note:="我的体态" //输出各变量所赋的值 fmt.Println(note+"\n姓名:"+name) fmt.Println("性别:",sex) fmt.Println("年龄:",age) fmt.Println("体重:",weight) fmt.Println("身高:",height) fmt.Println("BMI指数:",bmi)}运行结果如图。02常
量1.常量声明2.常量初始化常
量1.常量声明Go语言的常量使用关键字const声明,格式如下:const常量名[类型]=值常量必须在声明的同时就赋一个确定值,这是与变量不一样的地方。大家会发现,常量声明语句与单变量的赋值语句在形式上一样,其“类型”也可省略,由编译器来推导。例如:constefloat32=2.71828 //自然常数econstcint=299792458 //光速cconstg=6.67e-11 //引力常数G(省略类型)constpi=3.1416 //圆周率π(省略类型)constlanguagestring="Go语言" //字符串常量constsexbool=true //布尔型常量常
量也可以像变量声明那样批量声明一组常量,只须用关键字const搭配括号,如下:const( name="周何骏" sex=true weight=60 height=173)常量的值必须是能够在编译时就被确定的,可以在其赋值表达式中涉及计算过程,但是所有用于计算的值必须在编译期间就能获得,例如://错误(weight、height为变量,直到运行期才被赋值)varweight,height=60,173constbmi=weight/((height/100)^2)
//正确(weight、height为常量,在编译期就能得到值)constweight,height=60,173constbmi=weight/((height/100)^2)常
量2.常量初始化对于一组数值间存在递增(减)关系的常量,可以使用Go语言的常量生成器iota进行初始化。iota可自动生成一组以相似规则初始化的常量,而不用每行都写一遍初始化表达式。在一个const声明语句中,第1个声明的常量所在行的iota会被置为0,之后的每一个有常量声明的行iota会被自动加1,如下:const( c0=iota //c0==0 c1=iota //c1==1 c2=iota //c2==2 ... cn=iota //cn==n)也可以简写为:const( c0=iota //c0==0 c1 //c1==1 c2 //c2==2 ... cn //cn==n)常
量【实例2.3】用生成器iota初始化月份常量值。程序代码如下(const.go):packagemainimport"fmt"funcmain(){ const( month=iota Jan Feb Mar Apr ) fmt.Print(Jan,"月、",Feb,"月、",Mar,"月、",Apr,"月...")}运行结果如图。第2章Go语言基础运算符与表达式运算符与表达式1.运算符Go语言有几十种运算符,被分为了十几个类别,详见下表。优先级分
类运
算
符结合性1(最高)括号()、[]从左向右2单目运算符!、*(指针)、&、++、--、+(正号)、-(负号)从右向左3乘/除/取余*、/、%从左向右4加/减+、-从左向右5位移运算符<<、>>从左向右6关系运算符<、<=、>、>=从左向右7等于/不等于==、!=从左向右8按位“与”&从左向右9按位“异或”^从左向右10按位“或”|从左向右11逻辑“与”&&从左向右12逻辑“或”||从左向右13赋值运算符=、+=、-=、*=、/=、%=、>=、<<=、&=、^=、|=从右向左14逗号运算符,从左向右运算符与表达式2.优先级和结合性(1)算术运算符优先级同数学因Go语言中大部分算术运算符(包括加/减/乘/除/取余等)的优先级和数学中是一致的,故只要知道数学运算的优先级即可正确计算算术表达式的值,例如:vara,b,cint=2,4,8d:=a+b*c对于第2行程序语句中的表达式“a+b*c”,按照数学运算规则,应该先计算乘法,再计算加法。(2)加括号的部分最先算从上表可见,第1行括号的优先级为最高,故不管表达式如何复杂,都要首先计算其加括号的部分。例如,要想改变表达式“a+b*c”的求值顺序,先计算加法后计算乘法,只须对其加法部分加括号,语句改为如下:d:=(a+b)*c运算符与表达式(3)多个括号最内层最优先当表达式中有多个括号嵌套时,最内层的括号最优先。例如:constbmi=weight/((height/100)^2)计算时应当先执行内层括号里的“height/100”(将身高换算成米为单位),然后才执行外层括号的乘方(^2)运算。(4)其余遵循Go语言运算符优先级对于由多种不同类别运算符混合构成的表达式,则根据Go语言运算符的优先级来决定运算顺序,可参照上表。运算符的结合性是指,当相同优先级的运算符在同一个表达式中(且没有括号)时,计算的顺序,通常有“从左向右”和“从右向左”两个方向。运算符与表达式3.运算符测试(1)自增(++)和自减(--)运算符自增(如a++,a是变量)表示将变量值加1。Go语言为了保持简洁性,避免混淆和错误,取消了对前缀自增(如++a)的支持,这与绝大多数语言如C/C++、Java等都不一样。同理,自减也仅支持后缀自减(如a--),表示将变量值减1。另外,GO中的a++、a--等都是语句而非表达式,必须单独写为一行。【实例2.4】测试自增和自减运算符。程序代码如下(opt01.go):运行结果如图。运算符与表达式(2)位运算符位运算符是对变量值按其在计算机内部的二进制表示按位进行操作的一类运算符,介绍如下。①按位“与”(&)对参与运算的两个数值相应的二进制位进行与运算,规则为:0&0=0,0&1=0,1&0=0,1&1=1。②按位“或”(|)对参与运算的两个数值相应的二进制位进行或运算,规则为:0|0=0,0|1=1,1|0=1,1|1=1。③按位“异或”(^)对参与运算的两个数值相应的二进制位进行异或运算,即相同的是0、不相同是1:0^0=0,1^0=1,0^1=1,1^1=0。异或运算还有一个特别的性质,对于两个整数x、y,表达式(x^y)^y的值又会还原为x,利用这个特性可以对数值进行加密。④右移(>>)将一个数值的所有二进制位向右移若干位,右移后左边空出的位用0填充。向右移一位相当于整除2(舍弃小数部分)。⑤左移(<<)将一个数值的所有二进制位向左移若干位,右边空出的位填0。左边移出的位并不丢弃(依然有效),故左移一位相当于乘以2。运算符与表达式【实例2.5】测试位运算符。程序代码如下(opt02.go):运行结果如图。第2章Go语言基础基本数据类型01整
型整
型Go语言内置了多达12种整型,大体分为无符号与有符号两大类,各整型的名称、描述及取值范围如表。分类名称描
述取值范围无符号uint88位整型0~255byteuint8的别名0~255uint1616位整型0~65535uint3232位整型0~4294967295uint6464位整型0~18446744073709551615uint32或64位(基于架构)的整型—uintptr用于存放指针的整型(基于架构)—有符号int88位整型-128~127int1616位整型-32768~32767int3232位整型-2147483648~2147483647int6464位整型-9223372036854775808~9223372036854775807int32或64位(基于架构)的整型—整
型其中,uint、uintptr和int这3个类型是基于架构的,即它们的位数由实际运行程序的操作系统来决定,在32位操作系统上就是32位(4个字节)的整型,而在64位操作系统上则变成64位。不同类型的整型变量在相互赋值时必须进行强制类型转换,例如:varaint=2varbint32b=int32(a) //正确//b=a //错误fmt.Println("b=",b)整
型整型常量有十进制、八进制、十六进制三种表示法,十进制直接写出数值,八进制值以数字0开头,十六进制则以0x或0X开头,例如:variint=123 //十进制正整数fmt.Println("i=",i) //i=123
variint=-48 //十进制负整数fmt.Println("i=",i) //i=-48
variint=017 //八进制正整数fmt.Println("i=",i) //i=15
variint=-021 //八进制负整数fmt.Println("i=",i) //i=-17
variint16=32768fmt.Println("i=",i) //错误,超范围
variint=0x12a6 //十六进制数fmt.Println("i=",i) //i=4774(1*16^3+2*16^2+10*16+6)
vara,b=0xAB12,-0x1a0 //十六进制数fmt.Print("a=",a,",b=",b) //a=43794,b=-41602浮点型浮点型浮点型用于表示包含小数点的数值,Go语言内置两种浮点型:float32和float64,分别表示32位和64位的浮点数,它们都遵循IEEE754标准,该标准采用二进制数据的科学记数法来表示浮点数,如下。float32:用1位表示数字的符号,用8位表示指数(底数为2),用23位表示尾数,最大范围为3.40282346638528859811704183484516925440e+38。float64:用1位表示数字的符号,用11位表示指数(底数为2),用52位表示尾数,最大范围为1.797693134862315708145274237317043567981e+308。浮点型浮点型数有两种表示形式,如下。(1)十进制小数形式直接写出含小数点的数,当数的整数或小数部分为0时可省略小数点前或后的数字,但小数点两边的数字不能同时省略且小数点不能省略,例如:varffloat32=3.14fmt.Println("f=",f) //f=3.14
varffloat32=5.fmt.Println("f=",f) //f=5
varffloat32=.618fmt.Println("f=",f) //f=0.618
varffloat32=036.70fmt.Println("f=",f) //f=36.7
varffloat32=. //错误,小数点两边的数字不能同时省略fmt.Println("f=",f)浮点型(2)科学记数法形式如1.26×10-21表示为1.26e-21或1.26E-21,e或E的前面必须有数字且后面必须是一个正/负整数(正号可省略),例如:consthfloat64=6.62607015E-34 //普朗克常数fmt.Println("h=",h) //h=6.62607015e-34
constcfloat32=2.99792458e8 //真空中的光速fmt.Println("c=",c) //c=2.9979245e+08
constcfloat64=2.99792458e8fmt.Println("c=",c) //c=2.99792458e+08
constcfloat64=.299792458E09fmt.Println("c=",c) //c=2.99792458e+08
varffloat32=4.e+0fmt.Println("f=",f) //f=4
varffloat32=6E3fmt.Println("f=",f) //f=6000浮点型使用浮点型还要特别注意两点:(1)浮点型变量会被Go编译器默认推断为float64型。(2)目前的计算机事实上并不能精确表示和存储浮点数,因此不应当在程序中使用==或!=直接比较两个浮点数。例如:f1:=2.71828varf2float32=f1 //错误,f1为float64型varf2float32=float32(f1) //正确
constpi=math.Pi //圆周率πvarpfloat64=3.1415926 //祖冲之计算值fmt.Println(p==pi) //false,直接比较一定是不相等的fmt.Println(math.Abs(p-pi)<1e-6) //true,应当采用差的绝对值小于给定误差来判断03复数型复数型Go语言原生支持复数,内置了两种复数型:complex64和complex128。复数在计算机内部用两个浮点型数表示,一个为实部另一个为虚部。相应地,Go的复数型也由两个浮点型构成,complex64是由两个float32浮点型构成的,而complex128则是由两个float64浮点型构成的。在程序中,复数型数的写法与数学表示法一样,其实部和虚部数值的表示形式同浮点型,例如。此外,Go还有3个内置函数专用于处理复数,使用如下:varc=complex(2.718,0.618) //构造一个复数a:=real(c) //返回实部b:=imag(c) //返回虚部fmt.Print("c=(",a,"+",b,"i)") //c=(2.718+0.618i)04布尔型1.布尔运算2.布尔型的转换布尔型1.布尔运算布尔型无法参与数值运算,故不可用算术运算符(+、-、*、/、%等)对它进行操作,但可以用逻辑运算符(&&、||、!)将多个关系表达式、布尔型变量(或常量)组成一个逻辑表达式(布尔表达式)进行运算,称为“布尔运算”,规则为:(1)a&&b(“与”运算):只有a与b都为true,结果才为true;有一个为false,结果就为false。(2)a||b(“或”运算):只有a与b都为false,结果才为false;有一个为true,结果就为true。(3)!a(“非”运算):单目运算符!取与a值相反的布尔值,因此!true的值为false。布尔型布尔运算的结果一定也是布尔型值,另外,关系运算符(<、<=、>、>=、==、!=等)的比较操作也会产生布尔型的值。例如:fmt.Println(!true==false) //true
varb=88fmt.Println(b==86) //false
varx,y=14,8fmt.Println((x-y)<2*4) //truefmt.Println((x>y)&&((x-y)>7)) //false布尔型2.布尔型的转换在Go语言中,布尔型无法与其他数据类型直接转换,例如,不允许将布尔型强制转换为整型来参与算术运算:varb=truefmt.Println(int(b)+2)编译错误,输出信息:cannotconvertb(variableoftypebool)totypeint而且,布尔值也不会隐式转换为数值0或1,反之亦然,只能编写程序代码进行转换:varb=truefmt.Println(b+2) //错误varbVal=0ifb{ bVal=1}fmt.Println(bVal+2) //正确,输出3布尔型【实例2.6】布尔运算判断性别。程序代码如下(bool.go):packagemainimport( "fmt" "strings" //Go语言内置字符串处理包)funcmain(){ var( namestring="王燕" //姓名 profession="女博士" //身份 sexbool=true //性别(男:true;女:false) ) vargenderbool=strings.Contains(profession,"女")||!sex varsexString="男性" ifgender{ sex=false sexString="女性" } fmt.Println("sex=",sex) fmt.Print(name+"是一名",sexString)}运行结果如图。05字符串型1.字符串创建2.字符串访问3.字符串修改字符串型1.字符串创建Go语言将字符串作为一种原生的基本数据类型,创建一个字符串非常容易,如:vars="Hello,Go语言!"这句代码声明了字符串s,并初始化其内容为“Hello,Go语言!”。【实例2.7】字符串内容的两种引用方式。程序代码如下(string01.go):packagemainimport"fmt"funcmain(){ s1:="我爱\"Go语言\"编程\n@easybooks" //支持转义,但不能跨行 s2:=`我爱\"Go语言\"程序设计\n@easybooks` //可以跨行,但不支持转义 fmt.Println(s1) fmt.Println(s2)}运行结果如图。字符串型实际应用中,双引号使用最广泛,而反引号多用在书写多行消息文本、HTML源码及正则表达式的场合。Go语言的字符串是不可变的,但可以对其进行级联(+)和追加(+=)操作,例如:s:="我爱"+"Go语言编程!"fmt.Println(s) //我爱Go语言编程!s+="@easybooks"fmt.Println(s) //我爱Go语言编程!@easybooks字符串型2.字符串访问(1)单字节字符串访问如果一个字符串全部由单字节字符构成,就是“单字节字符串”,如:s1:="IloveGoprogramming!"s2:="HelloWorld!"s3:="Hello,Golanguage.@easybooks"单字节字符串可以通过索引直接提取其任意位置的字节,在方括号[]内写入索引,索引从0开始计数,如对于字符串s,s[0]访问其首字节,s[i-1]访问第i个字节,s[len(s)-1]则访问最后1个字节,如果想要获取字节所对应的字符内容,则通过string转换,如第i个字节的字符为string(s[i-1])。字符串型【实例2.8】单字节字符串的访问。程序代码如下(string02.go):packagemainimport"fmt"funcmain(){ s:="Hello,Golanguage.@easybooks" fmt.Println("总字节数:",len(s)) fmt.Println(s[0]) //索引位置为0(首字节)的ASCII码值 fmt.Println(string(s[0])) //索引位置为0(首字节)对应字符 fmt.Println(s[6:8]) //截取索引位置6~7(不包含最后8)的字符串 fmt.Println(s[18:]) //从索引位置18(对应字符@)一直截取至末尾 fmt.Println(s[:5]) //截取索引位置0~4(不包含最后5)的字符串}运行结果如图。字符串型(2)多字节字符串访问如果字符串的字符不全是单字节的(比如含有中文),就不能直接使用索引访问,Go语言专门提供了一个rune类型用于这类字符串的操作。rune是Go内部整型int32的别名,占4个字节(UTF-8编码最大字节),能表示不同字长的字符。使用时,先将待访问的字符串转换为rune型,然后就可以按单字节索引的方式获取指定位置的内容。【实例2.9】多字节字符串的访问。程序代码如下(string03.go):packagemainimport( "fmt" "unicode/utf8")funcmain(){ s:="Hello,Go语言。@easybooks" fmt.Println("总字节数:",len(s))//一个中文字符占3个字节 fmt.Println("总字符数:",utf8.RuneCountInString(s)) sc:=[]rune(s) //将字符串转为rune型 fmt.Println(sc[0]) //索引位置为0(首字节)的ASCII码值 fmt.Println(string(sc[0])) //索引位置为0(首字节)对应字符 fmt.Println(string(sc[6:11])) //截取索引位置6~10,不包含最后11(对应中文。) fmt.Println(string(sc[12:])) //从索引位置12(对应字符@)一直截取至末尾 fmt.Println(string(sc[:5])) //截取索引位置0~4(不包含最后5)的字符串}运行结果如图。字符串型3.字符串修改在Go语言中,不能直接修改字符串的内容,比如,下面这种试图修改指定字符的方式是不被允许的:s:="Hello,Go语言。@easybooks"s[6]="g"编译错误,输出信息:cannotassigntos[6](valueoftypebyte)要想修改字符串的内容,必须先将字符串复制到一个可写的变量中,然后再进行修改。对于单字节和多字节字符串来说,接收它们的变量类型是不同的。(1)单字节字符串修改单字节字符串复制到一个byte类型(Go字节类,uint8的别名)变量中,如下:字符串:="......"变量:=[]byte(字符串)变量[索引]='值' //注意值要用单引号(不能用双引号)引起来(2)多字节字符串修改多字节字符串修改则是先通过复制到一个rune类型变量,如下:字符串:="......"变量:=[]rune(字符串)变量[索引]='值' //注意值要用单引号(不能用双引号)引起来字符串型【实例2.10】两种字符串的修改。程序代码如下(string04.go):packagemainimport"fmt"funcmain(){ //单字节字符串修改 ss:="Hello,Golanguage.@easybooks" fmt.Println("单字节:",ss) bStr:=[]byte(ss) //转为byte型,字符串被自动复制到变量bStr bStr[6]='g' ss=string(bStr) fmt.Println("修改后:",ss)
//多字节字符串修改 sc:="Hello,Go语言。@easybooks" fmt.Println("多字节:",sc) rStr:=[]rune(sc) //转为rune型,字符串被自动复制到变量rStr rStr[9]='程' rStr[10]='序' sc=string(rStr) fmt.Println("修改后:",sc)}运行结果如图。第2章Go语言基础程序流程控制01条件语句条件语句条件语句又称if语句,它使部分程序代码块只有在满足特定条件时才会被执行,语法格式为:if<布尔表达式1>{ <语句块1>}[elseif<布尔表达式2>{ <语句块2>}...}elseif<布尔表达式n>{ <语句块n>}else{ <语句块n+1>}]说明:(1)该语句首先计算<布尔表达式1>的值,若是true,则执行<语句块1>,当<语句块1>执行完成,整个if语句也就结束了;当<布尔表达式1>的值是false时,再计算<布尔表达式2>,若是true,则执行第一个elseif部分的<语句块2>,当<语句块2>执行完成,整个if语句执行结束;……以此类推,若所有布尔表达式的值都是false时,就执行else部分的<语句块n+1>,执行完成后结束整个if语句。(2)整个语句只有if部分是必须的,后面所有的elseif和最后的else部分都是可选的,视程序逻辑需要可构成单独的一个if、if-elseif、if-else或者if-elseif-else等多种不同结构的if语句变体。(3)与其他语言不同,Go语言if语句中用于判断条件的布尔表达式不需要用括号括起来。条件语句(4)按照Go的语法,包裹每个语句块的前半个大括号“{”必须放在行尾,而不能另起一行。如下面这几种写法都是错误的:if<布尔表达式1>{ <语句块1>}elseif<布尔表达式2>{ //错误 <语句块2>}else{ <语句块3>}
if<布尔表达式1>{ //错误 <语句块1>}
if<布尔表达式1>{ <语句块1>}else{ //错误 <语句块2>}(5)Go语言没有其他语言都有的条件运算符(形如“表达式1?表达式2:表达式3”),因为用if语句就能够实现条件运算符的功能。条件语句【实例2.11】用条件语句判断用户输入年份是否为闰年。程序代码如下(if.go):运行演示如图。02分支语句分支语句分支语句又称switch语句,它会根据传入的参数检测并执行符合条件的分支,当程序有多个分支(两个以上)时,用它比用多个嵌套的if语句更加简明,其语法格式如下:switch[<表达式>]{case<表达式1>: [<语句1>] [fallthrough]case<表达式2>: [<语句2>] [fallthrough]...case<表达式n>:[<语句n>][default:<语句n+1>]}分支语句说明:(1)该语句首先计算<表达式>的值,然后判断该值与<表达式1>的值是否相等,若相等,则执行<语句1>;否则,继续判断<表达式>的值与<表达式2>的值是否相等,若相等,则执行<语句2>;……以此类推,若没有一个表达式的值与<表达式>的值相等,则执行default后面的<语句n+1>。(2)与其他语言不同,Go的switch语句中的每一个case都是独立的代码块,程序仅仅执行满足条件的那个case后面的语句,而不会像其他语言那样一直执行到底,故不需要通过break关键字跳出。(3)switch后面的<表达式>可省去,改由各个case后面的表达式直接判断执行条件,这种情况case后面的表达式就必须是布尔表达式,其效果等同于多重“if-elseif-else”结构的条件语句。(4)语句中的各条件表达式不限于数值常量,可以是任意支持相等比较运算的类型变量。(5)在一个case分支的语句中,可以通过fallthrough语句来强制执行下一个case分支的语句而不管其表达式条件是否满足。分支语句【实例2.12】用分支语句选择输出雷锋叔叔的名言。程序代码如下(switch.go):运行演示如图。03循环语句循环语句循环语句的作用是反复执行一段代码,直到不满足循环条件为止。Go语言遵循“少即是多”的设计哲学,只提供了for循环语句,语法格式如下:for初始化;循环条件;迭代部分{
循环体}说明:(1)初始化:该部分是一个表达式,可缺省不写。用来设置循环的初始条件,比如设置循环控制变量的初始值。(2)循环条件:这是一个布尔表达式,表示循环继续执行的条件,每一次循环体执行完后都要对该表达式求值,以决定是否继续循环。若该部分缺省不写,则表示条件永远为真(成为死循环)。(3)迭代部分:它也是一个表达式,同样可以缺省不写,用来改变循环控制变量的值,从而改变循环条件表达式的布尔值。循环语句(4)循环体:这是循环操作的主体部分,为任意合法Go语句组成的代码块,可以是一条语句,也可以是多条。for语句的执行流程是:第1步:首先计算“初始化”表达式,该表达式的值仅在此计算一次,以后不再计算。第2步:计算“循环条件”布尔表达式,若值为false,则结束整个for循环语句,程序继续执行紧跟在该for语句之后的语句;若值为true,则依次执行循环体中的语句。第3步:循环体执行一次后,计算“迭代部分”表达式,再转第2步。例如:vari,total=1,0forprice:=10.58;i<=100;i++{ total+=i ifi==100{ fmt.Println("price=",price) //price=10.58 }}fmt.Println("i=",i) //i=101fmt.Println("total=",total) //total=5050循环语句Go语言没有大多数语言的while和do-while循环,但仅用for语句也能实现与这两种循环完全一样的功能,如下。(1)while循环等价实现将for语句的初始化省略,原迭代部分移至循环体末尾,即可实现与while循环等价的功能,代码形式为:for循环条件{
循环体
迭代部分}例如:vari,total=1,0fori<=100{ total+=i i++}fmt.Println("total=",total) //total=5050循环语句(2)do-while循环等价实现将for语句的初始化、循环条件、迭代部分全部省略,迭代部分移至循环体末尾,其后用一个if语句判断对循环条件取反的布尔表达式值,若为true跳出循环,如此就能够实现与do-while循环等价的功能,代码形式为:for{
循环体
迭代部分 if!循环条件{ break }}例如:vari,total=1,0for{ total+=i i++ if!(i<=100){ break }}fmt.Println("total=",total) //total=5050循环语句【实例2.13】用循环语句设计一个计算阶乘的程序。说明:阶乘(!)是基斯顿·卡曼(ChristianKramp,1760~1826)于1808年发明的运算符号,一个自然数n的阶乘写作n!,是所有小于及等于该数的正整数的乘积,亦即n!=1×2×3×...×(n-1)×n,并且规定0!=1。程序代码如下(for01.go):packagemainimport"fmt"funcmain(){ varnint //接收输入自然数 fmt.Print("请输入:") fmt.Scanln(&n) vars=1 ifn!=0{ fori:=1;i<=n;i++{ s=s*i } } fmt.Print(n,"!=",s)}运行演示如图。循环语句【实例2.14】用循环语句设计一个程序,输出所有的水仙花数。说明:所谓水仙花数,是指一个3位数,其各位数字的立方和等于该数自身,例如,153=13+53+33。程序代码如下(for02.go):packagemainimport"fmt"funcmain(){ vari=0 //百位数 varj=0 //十位数 vark=0 //个位数 varn,p=0,0 fmt.Println("水仙花数有:") form:=100;m<1000;m++{ i=m/100 //得到百位数 n=m%100 j=n/10 //得到十位数 k=n%10 //得到个位数 p=i*i*i+j*j*j+k*k*k ifp==m{ fmt.Println(m) //打印水仙花数 } }}运行结果如图。04跳转语句1.goto语句2.break语句3.continue语句4.return语句跳转语句跳转语句用于改变程序流程的方向,简单直接。Go语言的跳转语句常与标签一起配合使用,标签标识一个语句,通常写在需要程序跳转到的目标位置,如下:标签名:
语句iGo的跳转语句包括goto、break、continue和return,下面分别举例说明它们的应用。1.goto语句goto语句可无条件地跳转到指定标签,格式为:...goto标签L...标签L:
语句i跳转语句
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026届湖南长沙市广益实验中学数学七年级第一学期期末复习检测模拟试题含解析
- 山东省威海乳山市2026届数学八年级第一学期期末教学质量检测模拟试题含解析
- 2026届北京市人民大附属中学数学七上期末考试模拟试题含解析
- 2026届益阳市重点中学数学七年级第一学期期末质量检测模拟试题含解析
- 农链引领未来:农产品溯源系统建设的新趋势与市场分析
- 高效环保产业助推下新型生物工程领域的发展策略探讨
- 2025企业管理资料范本销售岗劳动合同范本
- 2025中外合作经营企业劳动合同范本
- 中国银行汕尾市陆河县2025秋招笔试管理营销专练及答案
- 邮储银行内江市东兴区2025秋招笔试英语阅读选词题专练30题及答案
- 2025年甘肃省天水市供热有限公司招聘12人考试历年参考题附答案详解
- 妇科肿瘤影像学课件
- 育龄妇女生殖健康知识
- 临床护理实践指南试题库
- 线路改迁工程施工组织设计方案
- 人工智能导论-第2版-全套课件
- 《太赫兹时域光谱》课件
- 部编版六年级语文上册18《江南春》一等奖创新教学设计
- 2024-2025学年辽宁省沈阳市和平区南昌中学九年级(上)月考数学试卷(10月份)
- 第二单元 观察物体(单元测试)-2024-2025学年三年级上册数学北师大版
- 四川省挤塑聚苯板建筑保温工程技术规程
评论
0/150
提交评论