一、Go简介

Go是2009年开源的编程语言,Go语言具有以下特性:语法简洁、并发编程、编译迅速、数组安全、丰富的内置类型、错误处理、匿名函数和闭包、反射、函数多返回值、自动垃圾回收。

二、Go语言安装与配置

Go语言支持以下系统:Linux、Mac、Windows。

安装包下载地址:https://golang.org/dl/

如果打不开可以使用这个地址:https://golang.google.cn/dl/

下面介绍Windows和Linux系统的安装:

1、Windows系统下安装:

可以直接点击.msi进行下载,比如上述图片的go1.19.1.windows-amd64.msi,下载完后打开msi,进行安装,安装目录可以使用默认,也可以自己配置,安装目录不可以有中文。然后配置系统环境变量:添加GOROOT,值为Go的安装目录,例如D:\Program Files\Go。然后可以在cmd里执行go version,如果出现类似输出:go version go1.19.1 windows/amd64,说明安装配置成功,接下来就可以进行开发运行go程序了。

2、Linux系统下的安装:

1)下载二进制包:go1.19.1.linux-amd64.tar.gz

2)将下载的二进制包解压至/usr/local目录

tar -C /usr/local -xzf go1.19.1.linux-amd64.tar.gz

3)将 /usr/local/go/bin 目录添加至 PATH 环境变量:

export PATH=$PATH:/usr/local/go/bin

以上只能暂时添加 PATH,关闭终端然后下次再登录又没有了。
可以编辑 ~/.bash_profile 或者 /etc/profile,并将以下命令添加该文件的末尾,这样就可以永久生效:

export PATH=$PATH:/usr/local/go/bin

添加后需要执行:

source ~/.bash_profile
或者
source /etc/profile

三、Go语言开发结构与流程

以下程序是在windows系统的VS Code编辑器开发的,安装Go扩展可以方便开发。
Go语言程序的基本结构有以下几个组成:包声明、引入包、函数、变量、语句、表达式、注释。
以下是一个输出Hello, World!的main.go程序:

package mainimport "fmt"func main() {fmt.Println("Hello, World!")
}

打开命令行,在保存程序文件的目录中执行go run main.go,输出Hello, World!。

可以使用go build命令来生成二进制文件:

go build main.go

四、Go语言的基础定义

1、标识符:

Go语言标识符与其它语言类似,第一个字符必须是字母、下划线,不能是数字。

2、关键字

Go语言的25个关键字或者保留字:
var, type, switch, struct, select, return, range, package, map, interface, if, import, goto, go, func, for, fallthrough, else, default, defer, const, case, continue, chan, break.
Go语言的36个预定义标识符:
append, bool, byte, cap, close, complex, complex64, complex128, uint16, copy, false, float32, float64, imag, int, int8, int16, uint32, int32, int64, iota, len, make, new, nil, panic, uint64, print, println, real, recover, string, true, uint, uint8, uintptr.

3、注释:

// 单行注释
/*xxxxx多行注释*/

五、Go语言的数据类型

有如下类型:
1、数字类型
整型 int 和浮点型 float32、float64,Go 语言支持整型、浮点型数字和支持复数。
2、布尔类型
布尔型的值只可以是常量 true 或者 false。例子:var b bool = true。
3、字符串类型:
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。

六、Go语言变量与常量

1、声明变量与变量赋值

// 声明变量的一般形式是使用 var 关键字:
var variable type
// 也可以一次声明多个变量:
var variable1, variable2 type
// 声明变量时也可以赋值
var temp string = "ssss"
var a, b int = 1, 2

声明了变量并且赋值了,也可以不用写类型。

如果声明了变量没有赋值,那么变量的值为零值。比如var a bool的零值为false。

下面是一些类型数据的零值:

  • 数值类型(包括complex64/128)为0
  • 布尔类型为 false
  • 字符串为 “”
  • 以下几种类型零值为nil:
    var a *intvar a []intvar a map[string] intvar a chan intvar a func(string) intvar a error // error 是接口

声明变量更加简洁的方式:

a := 1

相当于:

var a int
a = 1

声明全局变量和函数变量:

ackage mainvar (  // 这种因式分解关键字的写法一般用于声明全局变量a intb bool
)// 这种不带声明格式的只能在函数体中出现
// c, d := 3123, "hello"func main(){c, d := 3123, "hello"
}

2、常量

常量是在程序运行时不会被修改的量。常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量的定义格式如下:

const variable [type] = value
你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型const a string = "abc"const a = "abc"
多个相同类型的声明可以简写为:
const c1, c2 = value1, value2

常量可以用len()等内置函数计算表达式的值,在常量表达式中,函数必须是内置函数,否则编译不通过

ackage mainconst (a = "abc"b = len(a)
)func main(){println(a, b)
}

iota是一种特殊常量,可以认为是一个可以被编译器修改的常量。iota在const关键字出现时将被重置为0,const中每新增一行常量声明,iota计数一次。

package mainimport "fmt"func main() {const (a = iota   //0b          //1c          //2d = "hh"   //独立值,iota += 1e          //"ha"   iota += 1f = 312    //iota +=1g          //312  iota +=1h = iota   //7,恢复计数i          //8)fmt.Println(a,b,c,d,e,f,g,h,i) // => 0 1 2 hh hh 312 312 7 8
}

3、变量作用域

作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。

Go语言中变量可以在三个地方声明:

  • 函数内定义的变量(局部变量):作用域只在函数体内,参数和返回值变量也是局部变量。
  • 函数外定义的变量(全局变量):在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。
  • 函数的形式参数:形式参数可以看作函数的局部变量。

七、Go语言运算符

Go语言运算符与java等语言基本一样,均有:算术运算符、关系运算符、逻辑运算符、赋值运算符、位运算符。
比较例外的是,Go语言有与C/C++类似的指针相关运算符:

运算符 描述 示例
* 指针变量 *a是一个指针变量
& 返回变量存储地址 &a: 变量的存储地址
package mainimport "fmt"func main() {var a int = 22var ptr *int// ptr变量存储了a的地址ptr = &afmt.Printf("a的值为 %d\n", a);fmt.Printf("ptr的值为 %s\n", ptr);fmt.Printf("*ptr的值为 %d\n", *ptr);
}

输出:

a的值为 22
ptr的值为 %!s(*int=0xc00000e0a8)
*ptr的值为 22

八、Go语言函数

Go语言程序至少有一个main函数。

1、函数定义

func function_name( [parameter list] ) [return_types] {// 函数体
}

2、函数使用

以下代码定义了函数和函数调用:

package mainimport "fmt"func main() {var a inta = sum(1, 2)fmt.Printf("a的值为 %d\n", a);
}func sum(a, b int) int {var c intc = a + breturn c
}

返回多个值的函数:

package mainimport "fmt"func swap(x, y string) (string, string) {return y, x
}func main() {a, b := swap("cc", "dd")fmt.Println(a, b) // 输出:dd cc
}

九、Go语言条件语句

Go语言条件语句的执行逻辑与其它语言是一致的(但是Go语言多了个select语句),主要是写法不同

1、if语句

定义:

if 布尔表达式 {/* 在布尔表达式为 true 时执行 */
}

示例:

package mainimport "fmt"func main() {var a int = 1if a < 10 {// 如果条件为true时执行以下语句fmt.Printf("a小于10\n" )}
}

if else 语句:

if 布尔表达式 {/* 在布尔表达式为 true 时执行 */
} else {/* 在布尔表达式为 false 时执行 */
}

2、switch语句

定义:

switch temp {case temp1:// case temp2://default://
}
或者
switch {case 布尔表达式1:// case 布尔表达式2://default://
}

示例:

package mainimport "fmt"func main() {var a string = ""var num int = 10switch num {case 123: a = "大于10"case 10: a = "等于10"case 1, 2: a = "小于10"default: a = "不知道"}switch {case a == "等于10":fmt.Printf("a等于10!\n" )    case a == "大于10", a == "小于10":fmt.Printf("a大于或者小于10!\n" )      default:fmt.Printf("其它情况\n" );}fmt.Printf("num的值为: %d, a的值为: %s", num, a );
}

输出:

a等于10!
num的值为: 10, a的值为: 等于10

fallthrough

使用fallthrough会强制执行后面的case语句,使用fallthrough时不会判断下一条 case 的表达式结果是否为 true,直接执行。

package mainimport "fmt"func main() {switch {case false:fmt.Println("1、case条件为false")fallthroughcase true:fmt.Println("2、case条件为true")fallthroughcase false:fmt.Println("3、case条件为false")fallthroughdefault:fmt.Println("默认case")}
}

输出:

2、case条件为true
3、case条件为false
默认case

3、select语句

select语句随机执行一个可运行的case,如果没有可运行的case,将阻塞运行,直到有 case 可运行,
每个case都必须是一个通信

定义:

select {case a: // 通信a// case b: // 通信b//default://
}

十、Go语言循环语句

Go语言循环的语法有点差别,for循环的写法也有差异,没有while循环。
示例:

// 循环遍历
for i := 0; i < count; i++ {//
}// 类似map遍历
for _, v := range map {//
}//
for 布尔表达式 {//
}
示例:
for 1 > 0 {fmt.Printf("111")
}

go循环程序中可以用break、continue、goto语句控制循环执行过程。

十一、Go语言数组

Go语言数组是具有相同唯一类型的一组长度固定的数据结构,这种类型可以是任意的原始类型例如整型、字符串,也可以是自定义类型。可以通过索引来读取或者修改数组元素。

1、一维数组

1)、数组声明:

var arr_name [size] type

例如:

var arr [3] int

2)、初始化数组

var arr = [2]float32{2.1, 3.3}

或者

arr := [2]float32{2.1, 3.3}

如果数组长度不确定,可以使用…代替数组的长度,编译器会根据元素个数自行推断数组的长度:

var arr = [...]float32{2.1, 3.3}
或者
arr := [...]float32{2.1, 3.3}

如果设置了数组的长度,还可以通过指定数组下标来初始化元素或者修改元素值:

arr := [2]float32{2.1, 3.3}
arr[1] = 1.1

2、多维数组

1)数组声明

var arr [size1][size2]...[size_n] type

例如三维数组:

var arr [4][22][3] int

下面以二维数组举例:

二维数组本质上是由一维数组组成的。

arr := [][]int{}// 可以使用append()函数向空的二维数组添加两行一维数组
row1 := []int{1, 2, 3}
row2 := []int{4, 5, 6}
arr = append(arr, row1)
arr = append(arr, row2)fmt.Println("arr为:", arr)
fmt.Println("第一个元素为:%d", arr[0][0])

也可以这样初始化二维数组:

arr := [2][4]int{{0, 1, 2, 3} ,{4, 5, 6, 7} , // ,不能省略
}

二维数组取值赋值:

赋值:
arr[2][1] = 222
取值:
a := arr[2][1]

3、数组作为函数参数:

void fun(param [3]int)
{//
}
或者不指定数组长度
void fun(param []int)
{//
}

十二、Go语言结构体

结构体是由相同类型或不同类型的数据组成的数据集合。

1、定义与使用

type struct_name struct {filed1 typefiled2 typefiled3 type
}

示例:

package mainimport "fmt"type Book struct {name stringauthor string
}func main() {stru := Book{"编程设计", "xian"}fmt.Println("stru为:", stru)var book1 Bookbook1.name = "js程序设计"book1.author = "xxx"fmt.Println("book1: ", book1)// 也可以使用key => value格式fmt.Println(Book{name: "编程设计", author: "xian"})
}

输出:

stru为: {编程设计 xian}
book1:  {js程序设计 xxx}
{编程设计 xian}

访问结构体成员:

结构体.成员名

2、结构体作为参数传递:

package mainimport "fmt"type Book struct {name stringauthor string
}func main() {stru := Book{"编程设计", "xian"}fmt.Println("stru为:", stru)getInfo(stru)
}func getInfo( book Book ) {fmt.Println( "Book name为: ", book.name)
}

输出:

stru为: {编程设计 xian}
Book name为:  编程设计

3、结构体指针

可以定义指向结构体的指针:

var struct_pointer *结构体名称 // 注意不是结构体变量名称

获取结构体变量地址:

struct_pointer = &str

使用指针访问结构体成员:

struct_pointer.name

十三、Go语言集合(Map)

Map是一种无序的键值对的集合。

1、定义map

// 声明变量,默认map是nil
var map_variable map[key_type]value_type// 或者使用make函数
map_variable := make(map[key_type]value_type)

示例:

package mainimport "fmt"func main() {var capitalMap map[string]stringcapitalMap = make(map[string]string)capitalMap["France"] = "巴黎"capitalMap["English"] = "伦敦"// capitalMap := map[string]string{"France": "巴黎", "English": "伦敦"}// 使用range遍历for k := range capitalMap {fmt.Println(k, " => ", capitalMap[k])}// 或者fmt.Println("\nk, v遍历: ")for k, v := range capitalMap {fmt.Println(k, " => ", v)}fmt.Println("\n")// 查看元素在集合中是否存在 */capital, ok := capitalMap["Itlay"]if (ok) {fmt.Println("Itlay的首都 ", capital)} else {fmt.Println("不存在Itlay的首都")}
}

delete删除:

delete(capitalMap, "France")

十四、Go语言range

for range循环可以对数组、字符串、slice、map等进行循环遍历。

1、遍历map

// 遍历map
for key, value := range map {map[key] = value
}

2、遍历数组

// 遍历数组
for i, val := range arr {// i代表索引,val代表相应的值
}

3、遍历字符串

// 遍历字符串。i是字符的索引,char是字符(Unicode的值)本身。
for i, char := range str {fmt.Println(i, char)
}

十五、Go语言切片

Go语言数组长度是固定的, 而切片提供了一种动态长度数组的功能。

1、创建切片与使用

可以使用make创建切片,len是数组的长度也是切片的初始长度。

var slice1 []type = make([]type, len)
或者
slice1 := make([]type, len)
// 也可以指定容量,capacity是可选参数
slice1 := make([]type, len, capacity)

切片初始化:

slice1 := []int{1,2,3 }

截取:

s := arr[startIndex:endIndex] // 左闭右开
s := arr[:endIndex]
s := arr[startIndex:]

len()方法获取切片长度,cap()测量切片容量。

切片在未初始化之前默认为nil,长度为 0:

var slice1 []int
// slice1 == nil

2、append()函数:切片追加新元素:

package mainimport "fmt"func main() {var slice1 []int // 创建切片fmt.Printf("长度=%d, 容量=%d, 切片=%v\n", len(slice1), cap(slice1), slice1)// 向切片添加一个元素slice1 = append(slice1, 33)fmt.Printf("长度=%d, 容量=%d, 切片=%v\n", len(slice1), cap(slice1), slice1)
}

输出:

长度=0, 容量=0, 切片=[]
长度=1, 容量=1, 切片=[33]

3、copy: 拷贝切片

package mainimport "fmt"func main() {var slice1 []int // 创建切片slice2 := []int{32, 43} // 创建切片// 向切片添加一个元素slice1 = append(slice1, 33)// slice1拷贝到slice2copy(slice2, slice1)fmt.Printf("长度=%d, 容量=%d, 切片=%v\n", len(slice2), cap(slice2), slice2) // => 长度=2, 容量=2, 切片=[33 43]
}

十六、Go语言接口

// 定义接口
type interface_name interface {method_name1 [return_type]method_name2 [return_type]method_name3 [return_type]...method_name_n [return_type]
}// 定义结构体
type struct_name struct {variable1 typevariable2 type...variable_n type
}// 实现接口方法
func (struct_variable_name struct_name) method_name1() [return_type] {/* 方法实现 */
}

示例:

package mainimport ("fmt"
)type Phone interface {speak()
}type IPhone struct {name string
}func (iPhone1 IPhone) speak() {fmt.Println("iPhone1 speak")
}func main() {var phone Phonephone = new(IPhone)phone.speak()
}

十七、Go语言并发

Go语言并发:通过go关键字来开启goroutine。goroutine是轻量级线程,goroutine的调度由Golang运行时进行管理。go语句开启一个新的运行期线程,即就是goroutine,以一个不同的、新创建的goroutine来执行一个函数。同一个程序中的所有goroutine共享同一个地址空间。

1、goroutine 语法格式:

go 函数名(参数列表)

示例:

package mainimport ("fmt""time"
)func printFun(s string) {for i := 0; i < 3; i++ {time.Sleep(200 * time.Millisecond)fmt.Println(s)}
}func main() {go printFun("World")printFun("Hello")
}

2、使用通道(channel)传递数据

可以使用通道(channel)用来传递数据。通道可在两个goroutine之间通过传递一个指定类型的值来通讯。操作符<-指定通道的方向:发送或接收。如果没有指定方向,说明是双向通道。

创建通道:

chan1 := make(chan int)
chan1 <- val    // 把 val 发送到通道 chan1
temp := <-chan1  // 从 chan1 接收数据, 并且赋值给temp变量

示例:

package mainimport "fmt"func sum(nums []int, c chan int) {sum := 0for _, v := range nums {sum += v}// 把sum发送到通道cc <- sum
}func main() {a := []int{31 , 21, 3, 4}chan1 := make(chan int)go sum(a[:len(a)/2], chan1)go sum(a[len(a)/2:], chan1)sum1, sum2 := <-chan1, <-chan1 // 从通道c中接收两个sum结果fmt.Println(sum1, sum2, sum1 + sum2) // => 7 52 59
}

最全的Go开发教程,超详细哦相关推荐

  1. r library car_基础方法 | 用R语言完成量化论文全流程示例!附超详细R脚本

    基础方法 ♪ Method R语言的优点 对于有一定数据分析基础的朋友们来说,要入门R语言并不是十分困难的.但是这毕竟是一门专业性很强的技术,我们当然希望投入精力掌握R语言之后能够得到相应的回报. 在 ...

  2. .Net魔法堂:史上最全的ActiveX开发教程——发布篇

    一. 前言 接着上一篇<.Net魔法堂:史上最全的ActiveX开发教程--开发篇>,本篇讲述如何发布我们的ActiveX. 二.废话少讲,马上看步骤! 1. 打包  C#开发的Activ ...

  3. maven配置阿里云_阿里云OSS PicGo 配置图床教程 超详细

    阿里云OSS和PicGo配置图床教程 超详细 废话不多说,直接开始 购买阿里云OSS服务 登录阿里云 打开侧边栏,选择对象存储OSS,如下图: 对象存储界面右部选择创建Bucket,如下图所示: 之后 ...

  4. svn安装教程 mysql_CentOS6.4 下安装SVN的详细教程(超详细)

    1.检查系统是否已经安装如果安装就卸载 rpm -qa subversion yum remove subversion 2.安装 yum install subversion 3.建立SVN库 mk ...

  5. .Net魔法堂:史上最全的ActiveX开发教程——部署篇

    一.前言 接<.Net魔法堂:史上最全的ActiveX开发教程--发布篇>,后我们继续来部署吧! 二. 挽起衣袖来部署   ActiveX的部署其实就是客户端安装ActiveX组件,对未签 ...

  6. 新版Android Studio(4.1.1 for Windows 64-bit)的安装教程(超详细)

    新版Android Studio(4.1.1 for Windows 64-bit)的安装教程(超详细) 获取Android Studio软件 在心仪的磁盘新建文件夹:AndroidStudio(文件 ...

  7. 【台大郭彦甫】Matlab入门教程超详细学习笔记二:基本操作与矩阵运算(附PPT链接)

    Matlab入门教程超详细学习笔记二:基本操作与矩阵运算 前言 一.基本操作 1.把matlab当作计算器使用 2.变量 3.控制格式输出 二.矩阵运算 1.矩阵 2.矩阵索引 3.使用:创建向量 4 ...

  8. windows安装Weblogic教程(图文教程超详细版)

    windows安装Weblogic教程(超详细) 一. 下载 WebLogic 到Oracle官网http://www.oracle.com/ 下载WebLogic(根据自己的情况选择),本文档下载的 ...

  9. 阿里云OSS PicGo 配置图床教程 超详细

    阿里云OSS和PicGo配置图床教程 超详细 废话不多说,直接开始 购买阿里云OSS服务 登录阿里云 打开侧边栏,选择对象存储OSS,如下图: 对象存储界面右部选择创建Bucket,如下图所示: 之后 ...

  10. exe电子书制作教程(超详细)【申明:来源于网络】

    exe电子书制作教程(超详细)[申明:来源于网络] 地址:http://wenku.baidu.com/view/0b046907eff9aef8941e0631.html

最新文章

  1. 【c语言】蓝桥杯算法提高 输出三个整数的最大数
  2. oracle expdp导出教程,Oracle Expdp Impdp 数据泵导入导出
  3. 51nod 1717 好数 (水题)
  4. java 条码识别_条码识别示例代码
  5. 本科生完成9篇SCI,担任顶刊审稿人!
  6. oracle 11 启动不了,求助,oracle 11g 启动失败,求大神帮忙看看,谢谢
  7. 浏览器了解(三)CSS解析
  8. Sun公司网站上的Swing实例,想学Swing的不看后悔
  9. java 去系统运行时间,JAVA WEB获取系统运行时间
  10. 如何使用ZEROBRANE STUDIO远程调试COCOS2D-X的LUA脚本
  11. 454. 四数相加 ||
  12. 华为这份关于专利的会议纪要,都说了什么?(内含华为十大发明彩蛋)
  13. BigDecimal解读
  14. 10——Filter过滤器
  15. 17暑期ACM俱乐部个人训练赛第1场 (石油oj) 7.24号
  16. 计算机软件也有“五大部分”
  17. 区块链开发的权威指南
  18. Android移动开发程序员的职业发展之路
  19. php输出圆周率100位,JS计算圆周率到小数点后100位实现步骤详解
  20. 联想微型计算机620S,小巧机身强劲性能 试用联想ideacentre 620s

热门文章

  1. LTE Cat 1 STM32 4G N58
  2. 数字电子技术实验作业(5)
  3. 4位数码管中间的冒号c语言,单片机4位数码管电子时钟(带闹钟,冒号为秒闪烁)...
  4. C++中的memset()函数
  5. 测试新人入职第一天都做什么?
  6. Android_01
  7. android室内定位传感器辅助pdr ,传感器辅助的WiFi指纹室内定位方法.pdf
  8. 【调剂】防灾科技学院资源与环境(专硕)专业接受地下水科学与工程、工程地质等多个专业考生调剂...
  9. SQL语言的数据类型
  10. 如何用Android studio开发一个实现基本功能的新闻app?——简闻(源码及教程)