一、特点和优势
简单:Go 语言的语法简洁、清晰,易于学习和阅读。这使得开发者可以更快地上手并编写高质量的代码
高效:Go 语言的编译速度非常快,而且生成的代码效率也非常高。此外,Go 语言支持并发编程,使得程序可以更加高效地利用多核CPU
可靠:Go 语言的类型系统非常严格,可以在编译时捕获许多常见的错误。此外,Go 语言还提供了内置的错误处理机制,使得程序可以更加健壮和可靠
并发:Go 语言原生支持 goroutine 和 channel 两种并发编程机制,使得编写高效、安全的并发程序变得更加容易
开发效率高:Go 语言的标准库提供了许多常用的功能,例如字符串处理、加密、网络编程和图像处理等。此外,Go 语言还拥有一个活跃的社区,提供了许多有用的第三方库和工具,使得开发者可以更加便捷地开发各种应用程序
跨平台性:Go 语言的编译器可以在多种操作系统上运行,包括 Windows、Linux、macOS 等。这使得开发者可以轻松地将程序移植到不同的平台上
二、基础语法和常用特性解析
2.1 注释
和c++的一样:
- 单行注释:以
//开头,可以在单行中使用。 - 多行注释:使用
/*作为起始,以*/作为结束。可以跨多行使用。
2.2 包导入
类似于python,。使用import关键字导入,可以导入标准库的自定义的包
import "fmt" // 导入标准库的fmt包
import "path/to/example" // 导入自定义包
用圆括号可以导入多个包
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
2.3 变量声明
需要声明才能使用,使用关键字var声明,且定义了的变量必须要使用,否则会报错
var name string
在函数内部使用简短声明方式
func add (a int, b int) int {
c := 5
return a + b + c
}
2.4 常量声明
也是const关键字声明,且必须初始化
var age int // 声明一个整数类型的变量
var pi float64 // 声明一个浮点数类型的变量
var isTrue bool // 声明一个布尔类型的变量
var name string // 声明一个字符串类型的变量
2.5 数据类型
- 基本类型:包括整数类型(如
int、int8、int16等)、浮点数类型(如float32、float64)、布尔类型(bool)、字符串类型(string)等。 - 复合类型:包括数组、切片、映射、结构体、指针、函数等。
var numbers [5]int // 声明一个包含5个整数的数组
var colors []string // 声明一个字符串切片
var person map[string]string // 声明一个字符串到字符串的映射
var student struct { // 声明一个结构体
name string
age int
}
var ptr *int // 声明一个整数类型的指针变量
var add func(int, int) int // 声明一个函数变量
2.6 控制流语句
-
条件语句:可以使用
if、else if和else关键字进行条件判断。注意没有圆括号了if age >= 18 { // 如果age大于等于18 fmt.Println("成年人") } else if age >= 12 { // 如果age大于等于12 fmt.Println("青少年") } else { // 否则 fmt.Println("儿童") } -
循环语句:可以使用
for关键字进行循环。
for i := 0; i < 5; i++ { // 执行5次循环
fmt.Println(i)
}
names := []string{"Alice", "Bob", "Charlie"}
for index, name := range names { // 迭代切片
fmt.Println(index, name)
}
- 选择语句:可以使用
switch关键字进行多条件选择。
day := 3
switch day {
case 1:
fmt.Println("星期一")
case 2:
fmt.Println("星期二")
case 3:
fmt.Println("星期三")
default:
fmt.Println("其他")
}
2.7 函数
使用func关键字定义函数
func add(a, b int) int {
return a + b
}
2.8 结构体
和c++类似,也使用.调用
type User struct {
ID int
Name string
Age int
}
func main () {
u := User{
ID = 1
Name = "aaa"
Age = 20
}
fmt.Println(p.Name, p.Age)
}
2.9 方法
可以为结构体定义方法,方法是一种与特定类型关联的函数。
type Rectangle struct {
length, width float64
}
func (r Rectangle) area() float64 {
return r.length * r.width
}
func main() {
rect := Rectangle{length: 10, width: 5}
fmt.Println(rect.area())
}
2.10 数组
var numbers [5]int // 声明一个包含5个整数的数组
numbers := [5]int{1, 2, 3, 4, 5} // 创建并初始化一个长度为5的整数数组
2.11 切片
是一个动态大小的、灵活的视图,可以对数组或其他切片进行操作。基本操作和python的类似
var colors []string // 声明一个字符串切片
colors := []string{"red", "blue", "green"} // 创建并初始化一个字符串切片
2.12 映射
映射是一种无序的键值对集合。
var person map[string]string // 声明一个字符串到字符串的映射
person := make(map[string]string) // 创建一个空的映射
person["name"] = "Alice" // 添加键值对
2.13 指针
指针是存储变量内存地址的变量。可以使用&操作符获取变量的地址,使用*操作符访问指针指向的值。
var age int = 30
var ptr *int = &age // 声明一个整数类型的指针变量,并初始化为age的地址
fmt.Println(*ptr) // 输出指针所指向的值
2.14 defer语句
defer语句用于延迟函数的执行,它会在当前函数返回之前执行。
func main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
// 输出结果:
// Hello
// World
2.15 错误处理
Go中的错误通常显式地使用返回值来表示。可以使用error类型作为函数的最后一个返回值,通过约定将其与其他返回值相关联。而不是使用异常。这提供了一种确保错误得到处理的方法,因为调用者必须显式地检查错误。
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
2.16 并发编程
Go具有内置的并发机制,可以轻松地编写并发程序。关键字go用于启动一个新的goroutine。
func sayHello() {
fmt.Println("Hello")
}
func main() {
sayHello()
go sayHello() // 在新的goroutine中执行sayHello函数
fmt.Println("World")
}
2.17 JSON数据处理
处理 JSON 是现代应用程序以及编码中的常见任务。Go 提供了简单的编码和解码机制。
type Car struct {
Make string `json:"make"`
Model string `json:"model"`
}
myCar := Car{Make: "Toyota", Model: "Corolla"}
carJson, _ := json.Marshal(myCar)
fmt.Println(string(carJson))