首先Go语言拥有很多优点: 1:高性能和高并发 2:语法简单,学习曲线平缓 3:丰富的数据库 4:完善的工具链 5:快速编译 6:静态链接 7:跨平台 8:垃圾回收
如此多的优点下,Go语言被越来越多的程序员和厂家使用,例如:字节,脸书等。因此学好Go语言可以为自己新增加一门技术,那么接下来就是Go语言的基础语法。
在Go语言中,分号(;)是用来分隔语句的。在大多数情况下,可以使用换行代替分号来分隔语句,这样可以使代码更加简洁和易读。
hello world:第一个小程序
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
在上述代码中,我们首先声明了一个 main 包。在Go语言中,main 包是一个特殊的包,它定义了一个可执行程序的入口点。
然后,我们通过 import "fmt" 导入了 fmt 包,该包提供了格式化输入输出的功能。
最后,我们在 main 函数中调用了 fmt.Println() 函数,并传递字符串 "Hello, World!" 作为参数。这个函数的作用是将参数打印到标准输出。
变量
定义通常采用以下格式
var 变量名 类型
常见的var定义方式有以下几种:
1:最普通的定义方法
var age int = 18
var name string = "字节"
2:编译器会自动推断出变量的类型
var age = 18
var name = "字节"
- 声明多个变量并初始化:
var x, y, z int = 1, 2, 3
var a, b, c = 1, "hello", true
- 省略类型和初始化(使用默认值):变量会被默认初始化为其对应类型的默认值,与其他语言类似
var age int
var name string
- 简短变量声明(仅在函数内部使用):
age := 18
name := "字节"
与其他语言类似,Go的变量也有自己的作用范围,这一点和其他语言是一样的。
扩容知识:除了var关键字,还可以使用其他关键字如const和type来定义常量和类型。
const PI = 3.14
type MyString string
for
Go里面唯一的遍历循环方式
for initialization; condition; post {
// 循环体代码
}
使用示例:
for i := 0; i < 5; i++ {
if i == 2 {
continue
}
fmt.Println(i)
}
如果不写条件相当于while(true)
if else
if语句用于判断一个条件是否为真,并根据结果执行相应的代码块。else语句则用于在if条件为假时执行另一段代码。与其他语言不一样的是if里面不需要加(),用法如下:
if condition {
// 条件为真时执行的代码块
} else {
// 条件为假时执行的代码块
}
示例:
package main
import "fmt"
func main() {
age := 18
if age >= 18 {
fmt.Println("您已经成年了")
} else {
fmt.Println("您还未成年")
}
}
switch
在Go语言中,switch语句用于根据不同的条件执行不同的代码块。它提供了一种更简洁的方式来实现多分支的逻辑判断。与其他语言不一样的是每一个case后面不用写break。用法如下:
switch expression {
case value1:
// 当expression等于value1时执行的代码块
case value2:
// 当expression等于value2时执行的代码块
...
default:
// 当expression不等于任何一个case时执行的代码块
}
示例
package main
import "fmt"
func main() {
fruit := "apple"
switch fruit {
case "apple":
fmt.Println("这是一个苹果")
case "banana":
fmt.Println("这是一个香蕉")
default:
fmt.Println("未知水果")
}
}
数组
数组是一种固定长度、拥有相同数据类型的元素序列。可以使用数组来存储一组具有相似特性的数据。由于长度的固定,其实数组在Go里面并不常用。基本语法如下:
var arrayName [size]dataType
创建示例:
var numbers [5]int
访问和修改数组元素的示例:
numbers[0] = 10 // 设置第一个元素的值为10
x := numbers[1] // 获取第二个元素的值并赋值给变量x
fmt.Println(numbers[2]) // 打印数组第三个元素的值
带有初始化值的数组声明示例:
var numbers = [5]int{1, 2, 3, 4, 5}
切片:Go独有的内容
切片(slice)是一种动态长度的、灵活的数据结构,它是基于数组的封装。切片提供了方便的操作和灵活的扩展性,常用于处理变长数据。可以理解为是没有长度的数组,类似java里面的集合。
声明语法:
var slice []ElementType
示例:
package main
import "fmt"
func main() {
// 创建一个整数类型的切片
numbers := []int{1, 2, 3, 4, 5}
fmt.Println(numbers) // 打印切片的所有元素
// 访问切片元素
fmt.Println(numbers[0]) // 打印第一个元素
// 修改切片元素
numbers[1] = 10
fmt.Println(numbers) // 打印修改后的切片
// 添加元素到切片末尾
numbers = append(numbers, 6)
fmt.Println(numbers) // 打印添加元素后的切片
// 切片的长度和容量
fmt.Println("长度:", len(numbers))
fmt.Println("容量:", cap(numbers))
}
读者很容易注意到append,这是切片的一个方法,很容易想到还有其他方法:
copy:用于将一个切片的内容复制到另一个切片,如果目标切片长度不够,则只会复制到目标切片长度的部分。它的使用方式为 copy(destSlice, srcSlice)。
source := []int{1, 2, 3}
destination := make([]int, len(source))
copy(destination, source)
fmt.Println(destination) // [1 2 3]
len 和 cap:len 和 cap 函数分别用于获取切片的长度和容量。
numbers := []int{1, 2, 3, 4, 5}
fmt.Println(len(numbers)) // 5
fmt.Println(cap(numbers)) // 5
切片的切割:可以通过切片表达式来获取原切片的子切片。切片表达式的语法为 slice[low:high],其中 low 是切片的起始索引,high 是切片的结束索引(不包括该索引对应的元素)。
numbers := []int{1, 2, 3, 4, 5}
subSlice := numbers[1:4]
fmt.Println(subSlice) // [2 3 4]
map
map 是一种集合类型,用于存储键值对(key-value)的无序集合。map 可以通过键来快速查找对应的值,类似于其他编程语言中的字典或哈希表,可以类比java学习。
声明语法:
var mapName map[KeyType]ValueType
使用示例:
package main
import "fmt"
func main() {
// 创建一个字符串到整数的映射
scores := make(map[string]int)
// 添加键值对
scores["Alice"] = 90
scores["Bob"] = 80
// 访问值
fmt.Println(scores["Alice"]) // 输出 90
// 修改值
scores["Bob"] = 85
// 删除键值对
delete(scores, "Alice")
// 判断键是否存在
score, ok := scores["Alice"]
fmt.Println(score, ok) // 输出 0 false
// 遍历map
for key, value := range scores {
fmt.Println(key, value)
}
}
range
range 是一个关键字,用于迭代遍历数组、切片、字符串、映射和通道等集合类型的元素。
以下是几种常见的使用方式:
//迭代数组或切片:
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
fmt.Println(index, value)
}
//迭代字符串
str := "Hello, World!"
for index, char := range str {
fmt.Println(index, string(char))
}
//迭代映射(map)
scores := map[string]int{"Alice": 90, "Bob": 80}
for key, value := range scores {
fmt.Println(key, value)
}
函数
函数是一段完成特定任务的代码块,它可以接收输入参数(可选),执行特定的操作,并返回结果(可选),与其他语言类似。但是他可以返回多个值。
函数的定义使用关键字 func,其基本语法如下:
func functionName(parameter1 type1, parameter2 type2, ...) returnType {
// 函数体代码
// 可以使用参数进行计算或执行其他操作
return result // 可选,用于返回结果
}
简单的示例:
func add(a, b int) int {
sum := a + b
return sum
}
以下是一个返回多个值的示例:
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
quotient := a / b
return quotient, nil
}
函数名为 divide,它接受两个 float64 类型的参数 a 和 b,并返回两个值:商和错误。
在函数体内,我们首先检查除数是否为零。如果除数为零,我们使用 errors.New 创建一个新的错误,并将其作为第二个返回值返回。否则,我们计算并返回除法的结果作为第一个返回值,并将第二个返回值设为 nil,表示没有发生错误。
指针
指针是一种特殊的数据类型,它存储了一个变量的内存地址。通过指针,我们可以直接访问和修改对应内存地址上的值。与c和c++类似,Go语言允许程序员使用指针。
使用实例:
func main() {
var num int = 10
var ptr *int // 声明一个指向int类型的指针
ptr = &num // 将指针指向num的内存地址
fmt.Println("Value of num:", num)
fmt.Println("Value of ptr:", ptr)
fmt.Println("Value at ptr:", *ptr) // 通过指针访问其指向的值
}
他在函数里面的使用的c++里面的使用是一样的,也有形参的区分。
结构体
结构体(Struct)是一种用户自定义的复合数据类型,用于组织和存储不同类型的数据字段。和c++里面的结构体是一样的。
使用实例:
//我们定义了一个名为 `Person` 的结构体,它有两个字段:`Name` 和 `Age`。这两个字段的类型分别是字符串和整数。
type Person struct {
Name string
Age int
}
//初始化:
p := Person{
Name: "Alice",
Age: 25,
}
结构体使用实例:
//结构体方法
type Rectangle struct {
Width float64
Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
我们定义了一个名为 Rectangle 的结构体,它有两个字段:Width 和 Height。然后,我们为 Rectangle 结构体定义了一个方法 Area,用于计算矩形的面积。
要调用结构体方法,需要使用结构体变量进行调用:
rect := Rectangle{
Width: 10,
Height: 5,
}
area := rect.Area()
fmt.Println("Area:", area)