【Go语言编程】基础知识篇
文章目录
- 一、Go语言简介
- 1.优势
- 2.劣势
- 3.前景
- 二、数据集的导入及编辑
- 1.包及其导入
- 2.变量
- 3.预定义常量
- 4.基础数据类型
- 5.派生数据类型
- 6.类型转换与类型别名
- 三、流程控制
- 四、数组、切片和映射
- 1.数组
- 2.切片
- 3.映射
- 五、string操作
- 1.连接字符串
- 2.解析字符串
- 1.遍历字符串
- 2.字符串操作
- 3.检查字符串长度
- 4.数据复制
- 六、函数
- 七、指针
- 1.指针的定义
- 2.Go语言中的指针
- 八、结构体和方法
- 1.结构体
- 2.方法
- 九、接口
- 1.错误的接口实现方法
- 2.空接口
- 3.类型断言、类型查询
一、Go语言简介
Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。
1.优势
- 兼顾C语言级别的编译、运行效率,容易部署,PHP级别的开发效率
- 强大的标准库,内置高效的垃圾回收机制
- 简单的并发编程,goroutine和channel极易上手
- 静态类型语言,拥有强大的编译检查、严格的编码规范
- 背景强大,由三位骨灰级大师创造,google公司运营维护
2.劣势
- 没有异常处理,只有Error
- 依赖管理(已解决√) 1.11推出GoModules
- 缺少框架(已解决√)Gin、Beego、Echo…等等
- 无泛型(正在解决。。。)官博确认正在考虑泛型设计,最快在1.18测试版中加入
3.前景
- 在云计算、微服务、基础后端软件上具有强大优势
- 得到诸多大厂的"青睐",很多部门由java转golang,新公司甚至直接使用golang
- 优秀开源项目不断涌现,以docker和k8s为代表
二、数据集的导入及编辑
1.包及其导入
- 点操作
import (."fmt")
//之后调用这个包函数时,可以省略前缀包名
Println("hello world")
- 别名操作
import (f"fmt")f.Println("hello world")
- _ 操作
_ 操作只是引入该包,当导入一个包时,它所有的init()函数就会被执行,无法通过包名调用包中的导出函数,只是为了简单地调用其init()函数。
2.变量
//变量声明//1.指定变量类型,声明后不赋值
var a int
a=12
//2.根据值自动推导变量类型
var b=12
//3.使用:=直接取代var关键字和变量类型
c:=10
//4.多变量声明中用于声明全局变量的写法
var (vname1 v_type1vname2 v_type2
)//匿名变量:_(下划线)是特殊的变量名,任何赋予的值都会被丢弃
_ ,b := 34,35
3.预定义常量
iota是一个常量计数器,可以认为是一个被编译器修改的常量,每个const关键字出现时被重置为0,然后在下一个const出现前,每出现一次iota,其代表的数字会自动加1,可以用于枚举。
package main
import "fmt"
func main(){const(a=iotabc)fmt.Println(a,b,c)
}//输出0 1 2
4.基础数据类型
- 布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换。
- int和int32在Go语言中被认为是两种不同的类型,但可以使用强制类型转换。
- 复数的表示
package main
import "fmt"
func main(){var v1 complex64v1=3.2+12iv2 :=3.2+12iv3:=complex(3.2,12)//获取实部和虚部fmt.Println(real(v1),imag(v1))
}
5.派生数据类型
- 指针pointer
- 数组array
- 切片slice
- 映射map
- 通道channel
- 结构体struct
- 接口interface
6.类型转换与类型别名
- Go语言不存在隐式转换,必须显式转换,且只能在两种互相兼容的类型间转换。
- Go语言支持使用关键字type为数据类型起别名。
package main
import "fmt"
type text string
func main(){var t text = "hello world"fmt.Println(t)
}
三、流程控制
- if、switch语句支持一个初始化语句,初始化语句和变量本身以分号(;)分隔。
package main
import("fmt")
func main(){if a:=3;a==3{fmt.Println("a==3")}
}
- Go语言默认每个case最后带有break关键字,匹配成功后不会自动向下执行,而是跳出switch语句。但是可以使用fallthrough关键字强制执行后面case的语句。
- Go语言只支持for循环,而不支持while和do…while结构。
- for…range可返回字符串索引、键值数据。
- goto关键字可用于任何语句中,作用是定点跳转到本函数内的标签。goto关键字不能跨函数跳转,也不能跳转至内层代码块中。
四、数组、切片和映射
1.数组
//声明与初始化
array1 :=[5] int{10,20,30,40,50}
array2 :=[...]int{10,20,30}
//初始化索引为1和2的元素
array3 :=[5]int{1:10,2:20}
//for...range遍历数组元素
package main
import("fmt")
func main(){var a[2]inta[0]=10a[1]=12for i,v:=range a{fmt.Println("Array element[", i, "]=",v)}
}
在go语言中数组是一个值类型,在函数体中无法修改传入的数组的内容。
2.切片
- 切片的三个属性:指针、长度和容量。
- 基于数组:数组切片可以只使用数组的一部分元素或者整个数组来创建,甚至可以创建一个比原数组还要大的数组切片。
- myArray[index1,index2]:包含index1,不包含index2,左闭右开。
- 直接创建切片:make()可以用于直接创建数组切片而不需要事先准备一个数组。
//创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间。
mySlice := make([]int,5,10)
myslice1 :=[]int{1,2,3,4,5}
- 切片共享同一段底层数组,如果一个切片修改了该底层数组的共享部分,那另一个切片也会相应发生改变。
- 切片只能访问到长度内的元素,试图访问超出其长度的元素会导致语言运行时异常。
- Go的内建函数:cap()和len(),返回容量和长度。
- append函数修改有余量的数组时,由于共享了底层数组,所以数组也会被修改。
- append函数会智能处理底层数组的容量增长。切片容量小于1000个元素时会成倍地增加容量;元素个数超过1000时,容量的增长因子会设为1.25。
- 切片复制时,加入的数组切片不一样大,就会按较小的数组切片的元素个数进行复制。
3.映射
//映射例子
inf :=map[int]string{110:"警察局",114:"查号中心",119:"消防局",120:"急救中心"
}
- 切片、函数以及包含切片的结构类型由于具有引用语义,不能作为映射的键。
- 映射的赋值:inf[110]=“警察局”。
- 元素的查询:同时获得值以及一个表示这个键是否存在的标志;只返回键对应的值,然后进行判断是否存在。
- 元素删除:delete(inf,110)。如果键不存在,这个调用什么都不会发生。但如果传入的map变量的值是nil,那么调用导致程序抛出异常。
五、string操作
字符串可以使用双引号“”定义,也能使用反引号’'定义。反引号最大的好处是支持跨行操作。
1.连接字符串
- 使用加法运算符
较少字符串连接的场景下直接使用加号运算符会使代码简短清晰,可读性好。
str1:="abcd"
str2:="efg"
str=str1+str2
- 调用fmt.Sprintln()函数
如果需要拼接的不仅仅是字符串,还有数字之类的其他需求的话,可以考虑fmt.Sprintln()函数。
str1:="abcd"
str2:="efg"
str:=fmt.Sprintln("%s%s",str1,str2)
- 调用string.Join()函数
在已有字符串数组的场合,使用strings.Join()函数有比较好的性能。
//需要import("strings")
str:=[]string{"ab","cd","ef"}
str:=strings.Join(str,"")
- 调用buffer.WriteString()函数
在一些性能要求较高的场合,尽量使用buffer.WriteString()函数以获得更好的性能。
//需要import("bytes")
var buf bytes.Buffer
buf.WriteString("abcd")
buf.WriteString("efg")
//输出buf.String()
这种方式比较理想,可以当作一个可变长字符串来使用,对内存的增长也有优化。如果能够预估字符串的长度,还可以用buffer.Grow()设置缓存容量。
2.解析字符串
1.遍历字符串
- 常规方式遍历字符串
- for…range方式遍历字符串
- 切片方式遍历字符串
先将字符串转成 []rune切片,然后用常规方式遍历。
2.字符串操作
- strings.Contains(s,substr string) bool
判断字符串s是否包含substr,返回一个布尔值。 - strings.Index(s,sep string) int
子串sep在字符串s中第一次出现的位置,不存在则返回-1。 - strings.Repeat(s string,count int) string
返回count个s串联的字符串。 - strings.Replace(s,old,new string,n int) string
返回将s中前n个不重叠old子串都替换为new,如果n<0,则替换所有old子串。 - strings.Split(s,sep string) []string
用sep分割s,会分割到结尾,并返回切片。如果sep为空,则Split将s切分成每一个unicode码值一个字符串。
3.检查字符串长度
除了“先将字符串转成 []rune切片,然后用常规方式遍历”方法外,还有其他三种方法。
- bytes.Count(s,sep []byte) int
如果参数sep为nil,返回s的Unicode代码点数+1;不为空则计算s有多少个不重叠的sep子切片。 - strings.Count(s,sep string) int
如果sep为空字符串,返回字符串的长度+1,否则计算字符串sep在s中出现的次数。 - utf8.RuneCountInString(s string) (n int)
返回s中的utf-8编码的码值的个数。错误或者不完整的编码会被视为宽度为1字节的单个码值。
4.数据复制
copy函数将第二个切片的元素复制到第一个切片中,复制长度为两切片中长度较小的那个。
六、函数
- 不定参数是指函数传入的参数个数为不定数量。如果参数列表中若干个相邻的参数类型相同,则可以在参数列表中省略前面变量的类型变量,在参数类型前面加上三个点“…”。
- 调用变参函数时,也可以将切片作为实参,不过需要展开,就是在切片后面加“…”。
- 如果希望传递任意类型,那么可以指定参数类型为接口interface{}。
- 匿名函数:不需要定义函数名的一种函数实现方法。
- 所有的匿名函数都是闭包。
- 闭包就是一个函数捕获了和它在同一作用域的其他变量或常量,只要闭包还在使用它,这些变量或常量就还存在。
七、指针
1.指针的定义
//声明指针
package main
import("fmt")
func main(){var ptrA *intvar ptrB = new(float32)var c float64ptrC := &c//分别为0,指针b,指针c//即未被初始化的指针为nil
}
Go语言指针不同于C/C++地方:不能在程序中对指针的值进行运算,即不支持指针的自增、偏移等。
但是它也为Go语言的垃圾回收机制提供了便利,不会因为垃圾回收而悬空指针。
2.Go语言中的指针
不支持"—>"运算符,直接用"."访问目标成员。
数组元素全为指针的数组称为指针数组。数组指针是指只想数组首元素的地址的指针,其本质为指针;指针数组是数组元素为指针的数组,其本质为数组。
区分数组指针和指针数组的方法:看"
*
"和谁结合。
如p *[5] int
,*
与数组结合说明是数组的指针;如p [5] *int
,*
与int结合,说明数组都是int类型的指针,是指针数组。
八、结构体和方法
1.结构体
type Student struct{ID intName stringAddress stringAge intClass stringTeacher string
}
var lm Student
- 如果一个结构体的成员变量名称的首字母大写,那么这个变量就是可导出的,导出是指这个变量可以在其他包进行读写。
//结构体的初始化
//第一种格式:顺序为每个成员变量指定一个值
type Point struct{X,Y int}
p:=Point{1,2}
// 第二种格式:指定部分或者全部成员变量的名称和值来初始化结构体变量,如果成员被忽略,默认用零值
lm := Student{ID:2021201}
2.方法
- Go语言的方法是运作在一个特定类型变量上的函数,该对象被称为方法的接收者。
- 方法属于函数,所以方法也是不能重载的;对于一个给定的类型和一个给定的名称,只会有一个方法。
- 根据方法接收者的不同类型,会出现重载的这种情况。
- 接收者不可以是接口,因为接口这种抽象的定义不能包含函数的具体实现。
- 方法的接收者类型本身不可以是指针类型,虽然方法接收者本身可以是一个指针。
type Person struct{}
type Ptr *Person
func (p Ptr) getName(){} //编译错误
func (p Person) getName(){}
func (p *Person)getName(){}
九、接口
接口是一系列方法的集合。接口定义了一组方法,但这些方法不包含代码,它们并不在接口中实现。
1.错误的接口实现方法
- 没有完全实现接口所定义的方法
- 用某一类型的变量直接对接口赋值
- 对不同的包中具有不可导出方法的接口进行实现
2.空接口
type Any interface{}
func funcA(args...interface{}) interface{}{}
空接口被称为"最小接口",没有任何方法,实现他们不需要满足任何要求。一个空接口变量可以被任意赋值,从而指向任何类型的对象。
最典型的例子是fmt库中的输出函数,通过配合空接口和类型查询,能够实现可接受任意对象实例并进行处理的函数。
3.类型断言、类型查询
一个接口变量所包含的值的类型有多种可能,为了动态判断接口代表的实际类型,需要利用Go语言的类型断言机制。
//检查变量varI是否是TypeA类型,判断并赋值
varC , ok := varI.(TypeA)
//类型查询
switch varC := varI.(type){case int:carC++case string:varC = "It's a string"...default:...
}
【Go语言编程】基础知识篇相关推荐
- Linux——Linux C语言编程基础知识
源程序的编译 在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 通常在gcc后跟一些选项和文件名来使用gcc编译器.gcc 命令的基本用法如下:: gcc [option ...
- c语言程序设计学了什么知识,初学C语言编程基础知识
初学C语言编程基础知识 初学C语言的人,很多基础知识是需要学习的,下面小编为大家带来了初学C语言编程的基础知识,欢迎大家阅读! 初学C语言编程基础知识 (1)学习过C语言的同学在对单片机有了基本了解之 ...
- 关于单片机的C语言编程基础知识(初学注意)
80C51上的C语言编程 C51的特色: (1)学习过C语言的同学在对单片机有了基本了解之后,就可以开始试着写一两个基于单片机的C语言的程序了.C51语言继承了ANSI C 的绝大部分的特性,基本的语 ...
- socket通信需要网线连接吗_socket网络编程基础知识篇
网络通信是一种进程间通信(IPC, Inter-Process Communication),要求位于不同网络节点不同进程的通信双方必须遵循统一的通信协议方可实现.基于套接字(Socket)通信是应用 ...
- c语言中指数形式怎么表示_C语言编程基础知识汇总学习,适合初学者!
我们用一个简单的c程序例子,介绍c语言的基本构成.格式.以及良好的书写风格,加深小伙伴们对C语言的认识. 例1:计算两个整数之和的c程序: #include main() { int a, ...
- r语言编程基础_这项免费的统计编程课程仅需2个小时即可学习R编程语言基础知识
r语言编程基础 Learn the R programming language in this course from Barton Poulson of datalab.cc. This is a ...
- SP 短信开发-基础知识篇
SP 短信开发-基础知识篇 很土的话题,但是最近帮朋友做这个东西,所以写点东西出来给初学者参考. 一.准备资料 SP开发资料网站上有很多,但是主要是以下几个文档: 1.MISC1.6 SP订购通知接口 ...
- 最全攻略:数据分析师必备Python编程基础知识
导读:本文主要介绍使用Python进行数据分析时必备的编程基础知识,主要涉及Python的基本数据类型.数据结构.程序控制.读写数据等内容. Python编写代码时,是以缩进作为代码块的标识,而不是使 ...
- FPGA笔记之verilog语言(基础语法篇)
文章目录 FPGA笔记之verilog语言(基础语法篇) 1. verilog 的基础结构 1.1 verilog设计的基本单元--module 1.2 module的使用 1.3 I/O的说明 1. ...
- c语言编程基础心得,C语言编程学习心得体会
C语言是在国内外广泛使用的一种计算机语言.其语言功能丰富.表达能力强.使用灵活方便.既具有高级语言的优点,又具有低级语言的许多特点,适合编写系统软件.本文是C语言编程学习心得,希望对大家有帮助. C语 ...
最新文章
- iOS提示气泡,带动画
- Python Xml类
- Python基础03 序列
- 【网络安全】文件上传绕过思路总结
- 友邦人寿引入阿里云PolarDB云数据库 支撑保险业务系统加速上云
- FFmpeg 源代码:avcodec_find_decoder()和avcodec_find_decoder_by_name()
- 前端学习(3342):ant design中grid排版使用
- 【2016年第5期】位置大数据在车辆保险风险管理中的应用
- 什么是LUT(LOOK UP TABLE)
- mysql乐观锁与事务_Mysql中的读锁,写锁,乐观锁及事务隔离级别和并发问题
- ui曲线谁是横坐标_【鼎阳硬件智库原创 | 测试测量】关于示波器的幅频特性曲线...
- iCloud 是什么
- 阿里云ubuntu 创建svn服务器
- 隋政军---将木屋烧烤打造成中国领先的烧烤品牌
- Oracle数据库表空间数据文件最大容量以及存满时处理方法
- React中文文档之State and Lifecycle
- Hive数据仓库数据分析
- AES - Openssl AES 函数说明
- 淘宝 API 开发步骤
- ​治理 V20 领导应如何支持
热门文章
- 如何恢复vscode的默认配置_VS恢复默认设置的2种方法
- 使用wrap和unwrap加密解密Oracle的PL/SQL对象(包,存储过程,函数等)代码
- 基于光耦的LED振荡电路
- 【PM学习笔记】酸梅干超人 - 零基础学B端UI设计 学习笔记
- 零基础开发一款微信小程序商城
- java吃货联盟的实训报告_作业:吃货联盟
- HDU 5457 Hold Your Hand【最小割+字典树】
- 【Python】Python Seaborn搞定线型回归图曲线
- 全球与中国雄激素和合成代谢类固醇市场发展前景与投资规划建议2021-2027年版
- 股票的基本概念和术语扫盲