Go介绍

什么是Go?

  • Go是一种跨平台的开源编程语言
  • Go可用于创建高性能应用程序
  • Go是一种快速、静态类型、编译语言,具有动态类型、解释语言的感觉
  • Go的语法类似于C++

Go的应用场景

  • 服务端Web开发
  • 开发基于网络的程序
  • 开发跨平台企业应用程序
  • 云原生开发

Go的特性

  • 快速的运行时和编译时间
  • 支持并发
  • 具有内存管理功能
  • 可以在不同平台上运行(Windows、Mac、Linux、Raspberry Pi等)

Go语言结构

一个Go文件的主要组成部分:

  • 包声明
  • 包导入声明
  • 函数
  • 变量
  • 语句和表达式

下面是一段简单的Go代码:

				
					package main
import ("fmt")

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

package main 表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。

func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。

当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected

执行Go程序

运行 hello.go 文件中的代码:

				
					$ go run hello.go
Hello World!
				
			

编译 hello.go 为二进制文件:

				
					$ go build hello.go
$ ls
hello   hello.go
$ ./hello
Hello World!
				
			

Go的数据类型

Go语言提供了多种数据类型,包括以下几种常见类型:

基本数据类型

  • bool:布尔类型,取值为true或false。
  • int、int8、int16、int32、int64:整数类型,分别表示不同位数的有符号整数。
  • uint、uint8、uint16、uint32、uint64:无符号整数类型,分别表示不同位数的无符号整数。
  • float32、float64:浮点数类型,分别表示32位和64位浮点数。
  • complex64、complex128:复数类型,分别表示32位和64位复数。
  • byte:类似于uint8的别名,表示一个字节。
  • rune:类似于int32的别名,表示一个Unicode码点。

字符串类型

字符串就是一串固定长度的字符连接起来的不可变序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。

复合类型

  • 数组(Array):由固定长度的相同类型元素组成的数据结构。
  • 切片(Slice):动态长度的可变序列,基于数组实现。
  • 结构体(Struct):由多个字段组成的复合数据类型,每个字段可以是不同类型。
  • 映射(Map):无序的键值对集合。
  • 通道(Channel):用于协程之间的通信和同步。

其他类型

  • 接口(Interface):定义了一组方法签名,用于实现多态。
  • 函数(Function):可独立执行的代码块,也可作为值传递。
  • 指针(Pointer):存储变量内存地址的数据类型。

Go语言条件控制语句

Go 语言提供了以下几种条件判断语句:

  • if语句
  • if…else语句
  • switch语句
  • select语句

前三者与传统编程语言类似。select 语句用于在多个通道操作中进行选择。它允许程序在多个通道上进行非阻塞的发送和接收操作。

select语句的语法如下:

				
					select {
case <-channel1:
    // 执行channel1接收操作
case data := <-channel2:
    // 执行channel2接收操作,并将接收到的数据存储在data变量中
case channel3 <- data:
    // 执行channel3发送操作,将data发送到channel3
default:
    // 当没有任何case满足条件时执行default块
}

				
			

select语句的工作方式如下:

  • 如果有任何一个case语句可以立即执行(即通道操作不会阻塞),则将执行该case语句。
  • 如果有多个case语句可以立即执行,Go语言会随机选择一个case进行执行。
  • 如果没有任何case可以立即执行,且存在default块,则会执行default块。
    如果没有任何case可以立即执行,且没有default块,select语句将被阻塞,直到至少有一个case可以执行。

select语句常用于处理并发操作,例如同时监听多个通道的数据,或者在多个任务之间进行调度。它提供了一种简洁而有效的方式来处理并发情况下的选择操作。

select 语句的使用示例:

				
					package main

import (
	"fmt"
	"time"
)

func main() {
	c1 := make(chan string)
	c2 := make(chan string)

	go func() {
		time.Sleep(1 * time.Second)
		c1 <- "one"
	}()

	go func() {
		time.Sleep(2 * time.Second)
		c2 <- "two"
	}()

	for i := 0; i < 2; i++ {
		select {
		case msg1 := <-c1:
			fmt.Println("Received", msg1)
		case msg2 := <-c2:
			fmt.Println("Received", msg2)
		}
	}

}

				
			

Go的函数

Go 语言函数定义格式如下:

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

函数可以接受零个或多个参数,并可以返回零个或多个值。参数和返回值可以是任何有效的Go语言类型。例如:

				
					func swap(a, b int) (int, int) {
    return b, a
}
				
			

函数可以像其他值一样被赋值给变量,并作为参数传递给其他函数。如:

				
					func applyOperation(numbers []int, operation func(int) int) {
    for i, num := range numbers {
        numbers[i] = operation(num)
    }
}
				
			

可以在函数内部定义匿名函数,也称为闭包函数。这些函数可以访问其外部函数的变量。

Go的指针

一个指针变量指向了一个值的内存地址。

Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

指针变量声明格式如下:

				
					var var_name *var_type
				
			

在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。

指针的代码示例:

				
					a := 20     //声明实际变量
var ip *int //声明指针变量
ip = &a     // 指针变量的存储地址

fmt.Printf("a 变量的地址是: %x\n", &a)
fmt.Printf("ip 变量储存的指针地址: %x\n", ip) // 指针变量的存储地址
fmt.Printf("*ip 变量的值: %d\n", *ip)    // 使用指针访问值
				
			

Go的结构体

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:

				
					type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}
				
			

定义了结构体类型,它就能用于变量的声明,语法格式如下:

				
					variable_name := structure_variable_type {value1, value2...valuen}
或
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
				
			

结构体的使用示例:

				
					import "fmt"

type Person struct {
	firstName string
	lastName  string
	gender    string
	age       int
}

func main() {
	jon := Person{"Jon", "Snow", "Male", 18}
	fmt.Println(jon)
}
				
			

Go的数组

声明数组:

				
					var variable_name [size] variable_type
// 多维数组
var variable_name [size1][size2]...[sizeN] variable_type
				
			

初始化数组:

				
					heroes := [5]string{"Steve Rogers", "Tony Stark", "Natasha Romanov"}
	//可以用...自行推断数组的长度
	casts := [...]string{"Chris Evans", "Robert Downey Jr.", "Scarlet Johnson"}
	//如果设置了数组长度,可以指定下标来初始化元素
	profiles := [5]string{1: "wearing an iron suit", 0: "super soldier", 2: "an agent"}
				
			

Go的映射

可以使用内建函数 make 或使用 map 关键字来定义 Map:

				
					map_variable := make(map[KeyType]ValueType, initialCapacity)
				
			

例如:

				
					capital := make(map[string]string, 2)
				
			

其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。Map 的容量是指 Map 中可以保存的键值对的数量,当 Map 中的键值对数量达到容量时,Map 会自动扩容。如果不指定 initialCapacity,Go 语言会根据实际情况选择一个合适的值。

也可以使用字面量创建 Map:

				
					language := map[string]string{
		"China":       "Chinese",
		"Japan":       "Japanese",
		"South Korea": "Korean",
	}
				
			

获取元素:

				
					l1, existed := language["South Korea"]//l1的值为键的映射值或该类型的零值,existed的值为true/false
				
			

修改元素:

				
					language["America"] = "English"
				
			

获取 Map 的长度:

				
					clen := len(capital)
				
			

遍历 Map:

				
					for k, v := range capital {
		fmt.Printf("%s:%s\n", k, v)
	}
				
			

删除元素:

				
					delete(capital, "China")
				
			

Go语言范围

Go语言中的 range 关键字可用于for循环中迭代数组、切片、通道或集合的元素。格式如下:

				
					for k, v := range collection_name {
		//operations to key and value
	}
	
	for k := range collection_name {
		//operations to key
	}
	
	for _, v := range collection_name {
		//operations to value
	}
				
			

Go的类型转换

Go中的类型转换基本格式如下:

				
					type_name(expression)
				
			

数值类型转换示例:

				
					var i = 10
var f = float64(i)
				
			

将一个字符串转换成另一个类型,可以使用以下语法:

				
					s := "0.002"
var n int
n, _ = strconv.Atoi(s)
				
			

以上代码将字符串变量 str 转换为整型变量 num。

参考菜鸟教程