首先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)