Go 语言速成指南(一)
把所有的代码跟着敲一遍,基本语法全部能掌握🫡
变量
变量定义
package main
import "fmt"
func main() {
// 变量定义有两种方式
// 方式一:var定义
var words string = "hello world"
fmt.Println(words)
// 方式二:`:`定义, 自动推断变量类型
sentences := "hello go"
fmt.Println(sentences)
}
注释:方式二的定义方法只能在函数中使用。
内建变量类型
package main
import "fmt"
func main() {
// Go 语言内建类型分为5种,分别是整数类型、浮点数类型、字节类型、复数类型以及布尔类型
// 整数类型
// 定义一个Int类型的整数,int 默认是4字节
var a int = 10
fmt.Println(a)
// 定义一个Int8类型的整数
var b int8 = 10
fmt.Println(b)
// 定义一个uint类型的整数
var c uint = 10
fmt.Println(c)
// 浮点数类型,不同于其它语言,浮点数类型名称都是float,没有double
var d float32 = 10.5
fmt.Println(d)
// 字节类型
var e byte = 'a'
fmt.Println(e)
var f rune = '你'
fmt.Println(f)
// 复数类型 3+3i
var g complex64 = 3 + 3i
fmt.Println(g)
// 布尔类型
var h bool = true
fmt.Println(h)
}
10
10
10
10.5
97
20320
(3+3i)
true
重点说明rune类型,其本质是一个Int类型,它的出现主要是为了解决Unicode字符和utf-8编码的问题。
常量
常量声明
// 声明单个常量
const PI = 3.14
// 声明多个常量
const (
StatusOk = 200
NotFound = 404
Forbidden = 403
)
常量枚举
package main
import "fmt"
func main() {
fmt.Println("圆周率:", PI)
fmt.Println("状态码OK: ", StatusOk)
fmt.Println("状态码NotFound: ", NotFound)
fmt.Println("Forbidden: ", Forbidden)
// 常量用来枚举
const (
Red = iota // 默认是0开始
Green
Blue
)
fmt.Println("红色的枚举值:", Red)
fmt.Println("绿色的枚举值:", Green)
fmt.Println("蓝色的枚举值:", Blue)
// 常量表达式可以执行任意精度的计算
const b = 3e20 / PI
fmt.Println("b: ", b)
}
条件语句
if-else
// 基本的if语句
num := 10
if num%2 == 0 {
fmt.Println(num, "是偶数")
}
// if-else
if num > 0 {
fmt.Println(num, "是正数")
} else {
fmt.Println(num, "是负数")
}
// if-else if
if num > 10 {
fmt.Println(num, "大于10")
} else if num == 10 {
fmt.Println(num, "等于10")
} else {
fmt.Println(num, "小于10")
}
// 用if语句定义局部变量
if scope := 24; scope > num {
fmt.Println("scope > num")
}
switch case
package main
import "fmt"
func main() {
// switch case 是个值
n := 3
switch n {
case 1:
fmt.Println("n == 1")
case 3:
fmt.Println("n == 3")
default:
fmt.Println("n == xx")
}
// switch case 是个表达式
switch {
case n%2 == 0:
fmt.Println("n是奇数")
default:
fmt.Println("n是偶数")
}
}
循环语句
基本for循环
// 基本的for
for i := 0; i < 5; i++ {
fmt.Printf("第%d次循环\n", i)
}
省略部分元素的for循环
// for省略前置语句
j := 5
for ; j > 0; j-- {
fmt.Printf("第%d次循环\n", j)
}
while风格的for
// for循环只包含条件表达式,类似while语句
k := 0
for k < 5 {
fmt.Printf("第%d次循环\n", k)
k++
}
无限循环
//无限循环 相当于while true
for {
fmt.Println("进入死循环")
}
for range循环
// for range 遍历字符串
for index, char := range "hello" {
fmt.Printf("index: %d , charactor is %c\n", index, char)
}
// 遍历map
m := map[string]int{"a": 1, "b": 2}
for key, value := range m {
fmt.Printf("key is %s and value is %d\n", key, value)
}
// 遍历通道
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
for n := range ch {
fmt.Println("从通道取值:", n)
}
数组
数组基础用法
// 定义长度为5的数组,默认值为0
var a [5]int
fmt.Println("array-a: ", a)
// 设置数组特定位置的值
a[4] = 100
fmt.Println("array-a: ", a)
// 获取数组的长度
fmt.Println("array-a的长度是:", len(a))
// 使用数组字面量初始化并赋值
b := [5]int{12, 3, 4, 5, 6}
fmt.Println("array-b: ", b)
// 二维数组声明和初始化
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("array-twoD: ", twoD)
// 声明数组省略长度,编译器自动计算
c := [...]int{6, 7, 8}
fmt.Println("array-c: ", c)
// 遍历数组 -- 不介绍了,一般都是for range遍历
数组作为参数传值
package main
import "fmt"
func modifyArray(arr [5]int) {
arr[0] = 100
fmt.Println("modify arr: ", arr)
}
func main() {
// 重点:数组传参是传值!!
d := [5]int{1, 1, 1, 1, 1}
fmt.Println("before modify: ", d)
modifyArray(b)
fmt.Println("after modify: ", d)
}
before modify: [1 1 1 1 1]
modify arr: [100 3 4 5 6]
after modify: [1 1 1 1 1]
从结果上来看,原来的数组元素根本没有被修改,这是因为数组作为参数是“传值”操作,形参是拷贝数组所有元素,函数内的操作都是针对实参的副本元素进行操作,当函数执行结束后,形参被销毁。因此,不会对原来的数组造成任何影响。
那么如何能做到在一个函数里修改原来数组元素的操作呢?那就要继续学习切片的知识。