GO基础语法一
- 一、编写第一个Go程序
- 1、基本程序结构
- 2、应用程序入口
- 3、退出返回值
- 4、获取命令行参数
- 二、变量,常量以及与其他语言的差异
- 1、编写测试程序
- 2、实现Fibonacci数列
- 3、变量赋值
- 4、常量定义
- 三、数据类型
- 1、类型转化
- 2、类型的预定义值
- 3、指针类型
- 四、运算符
- 1、算数运算符
- 2、比较运算符
- 3、用==比较数组
- 4、逻辑运算符
- 5、位运算符
- 五、循环
- 1. 基本的 **for** 循环:
- 2. **for range** 循环:
- 3. **while** 条件循环:
- 4. 无限循环:
- 5.if条件
- 1. 基本的 if 语句:
- 2. if 语句的条件可以包含初始化语句:
- 3.多个 if 语句的嵌套
- 6.switch条件
一、编写第一个Go程序
1、基本程序结构
package main //包,表名代码所在的模块(包)import "fmt" //引入代码依赖//功能实现
func main(){fmt.Println("Hello,World!")}
2、应用程序入口
- 必须是main包 package main
- 必须是main方法 func main()
- 文件名不一定是main.go
3、退出返回值
与其他主要变成语言的差异
- Go中的main函数不支持任何返回值
- 通过os.Exit 来返回状态
4、获取命令行参数
与其他主要变成语言的差异
-
main函数不支持传入参数
func main~~(arg []string)~~
-
在程序中直接通过os.Args获取命令行参数
二、变量,常量以及与其他语言的差异
1、编写测试程序
- 源文件以_test结尾:xxx_test.go
- 测试方法以Test开头:func TestXXX(t *testing.T){}
package testimport ("log""testing"
)func TestFirstTry(T *testing.T){log.Print("My first try!")
}
2、实现Fibonacci数列
1,1,2,3,5,8,13,…
package fibimport ("testing"
)// TestFibList 是测试斐波那契数列生成函数的单元测试函数
func TestFibList(t *testing.T) {var a int = 1var b int = 1// 另一种变量声明方式:// var (// a int = 1// b = 1// )// 或者使用短变量声明方式:// a := 1// b := 1// 输出变量 a 的值t.Log(a)// 循环生成斐波那契数列的前5个数并输出for i := 0; i < 5; i++ {// 输出变量 b 的值t.Log(b)// 交换 a 和 b 的值,生成下一个斐波那契数tmp := aa = bb = tmp + a}
}
3、变量赋值
与其他主要变成语言的差异
- 赋值可以进行自动类型推断
- 在一个赋值语句中可以对多个变量进行同时赋值
package fibimport ("testing"
)// TestExChange 是测试变量交换函数的单元测试函数
func TestExChange(t *testing.T) {// 初始化两个变量 a 和 b 的值a := 1b := 2//temp :=a //a=b//b=temp// 使用短变量声明方式,同时交换 a 和 b 的值// 在 Go 中,可以通过这种方式轻松地实现两个变量的值交换a, b = b, a// 输出交换后的变量值t.Log(a, b)
}
输出结果:
4、常量定义
与其他主要变成语言的差异
快速设置连续值
iota枚举
Go里面有一个关键字iota
,这个关键字用来声明enum
的时候采用,它默认开始值是0,const
中每增加一行加1:
package constan_testimport "testing"// 第一个常量组,使用 iota 枚举星期几
const (Monday = iota + 1TuesdayWednesday
)// 第二个常量组,使用 iota 创建一组表示文件权限的常量
const (Readable = 1 << iota // 位运算左移,表示可读Writable // 位运算左移,表示可写Executable // 位运算左移,表示可执行
)// TestConstanTry 是测试星期几常量的单元测试函数
func TestConstanTry(t *testing.T) {// 输出星期几的常量值t.Log("星期一:", Monday)t.Log("星期二:", Tuesday)t.Log("星期三:", Wednesday)
}// TestConstanTry1 是测试文件权限常量的单元测试函数
func TestConstanTry1(t *testing.T) {//a:=7 // 二进制表示为 0111 TRUE TRUE TRUE a := 1 // 二进制表示为 0001 true false false// 使用位运算检查文件权限t.Log("可读:", a&Readable == Readable) t.Log("可写:", a&Writable == Writable)t.Log("可执行:", a&Executable == Executable)
}
三、数据类型
数据类型 | 描述 | 示例 |
---|---|---|
int | 有符号整数类型,大小取决于计算机架构,常用于表示整数。 | var x int = 10 |
int8 | 有符号8位整数类型,范围为-128到127。 | var x int8 = 127 |
int16 | 有符号16位整数类型,范围为-32768到32767。 | var x int16 = -300 |
int32 | 有符号32位整数类型,范围为-2147483648到2147483647。 | var x int32 = 100000 |
int64 | 有符号64位整数类型,范围为-9223372036854775808到9223372036854775807。 | var x int64 = -9223372036854775808 |
uint | 无符号整数类型,大小取决于计算机架构,常用于表示正整数。 | var x uint = 10 |
uint8 | 无符号8位整数类型,范围为0到255。 | var x uint8 = 255 |
uint16 | 无符号16位整数类型,范围为0到65535。 | var x uint16 = 65535 |
uint32 | 无符号32位整数类型,范围为0到4294967295。 | var x uint32 = 4294967295 |
uint64 | 无符号64位整数类型,范围为0到18446744073709551615。 | var x uint64 = 18446744073709551615 |
float32 | 32位浮点数类型,可表示小数。 | var x float32 = 3.14 |
float64 | 64位浮点数类型,可表示小数。 | var x float64 = 3.14 |
complex64 | 由两个32位浮点数表示的复数类型。 | var x complex64 = 3 + 4i |
complex128 | 由两个64位浮点数表示的复数类型。 | var x complex128 = 3 + 4i |
byte | uint8 的别名,常用于表示ASCII字符。 | var x byte = ‘A’ |
rune | int32 的别名,常用于表示Unicode字符。 | var x rune = ‘你’ |
string | 字符串类型,表示一串字符。 | var x string = “Hello” |
bool | 布尔类型,表示真或假。 | var x bool = true |
array | 数组类型,固定大小的元素序列。 | var x [3]int = [3]int{1, 2, 3} |
slice | 切片类型,可变大小的元素序列。 | var x []int = []int{1, 2, 3} |
map | 映射类型,存储键值对的无序集合。 | var x map[string]int = map[string]int{“a”: 1, “b”: 2} |
struct | 结构体类型,自定义的复合数据类型。 | type Person struct {Name string; Age int} |
1、类型转化
与其他主要变成语言的差异
- Go语言不允许隐式类型转换
- 别名和原有类型也不能进行隐式类型转换
2、类型的预定义值
math 包提供了一些常用类型的预定义值,包括整数、浮点数等。以下是三个例子:
- math.MaxInt64
- math.MaxFloat64
- math.MaxUint32
package math_constantsimport ("fmt""math"
)func ExampleMaxInt64() {// 输出 int64 类型的最大值fmt.Printf("int64 类型的最大值:%d\n", math.MaxInt64)
}
func ExampleMaxFloat64() {// 输出 float64 类型的最大值fmt.Printf("float64 类型的最大值:%f\n", math.MaxFloat64)
}
func ExampleMaxUint32() {// 输出 uint32 类型的最大值fmt.Printf("uint32 类型的最大值:%d\n", math.MaxUint32)
}func main() {ExampleMaxInt64()ExampleMaxFloat64()ExampleMaxUint32()
}
这些预定义值对于处理数值边界和范围非常有用。
3、指针类型
与其他主要变成语言的差异
- 不支持指针运算
在 Go 语言中,指针的使用受到一些限制,其中最明显的一点是不支持指针运算。以下是一个简单的例子,说明了指针运算在 Go 中是不允许的:
package pointer_testimport "testing"// TestPointerArithmetic 是测试指针运算的单元测试函数
func TestPointerArithmetic(t *testing.T) {// 定义一个整数变量 x,并赋值为 10x := 10// 定义一个指向整数的指针变量 p,指向 x 的内存地址p := &x// 尝试进行指针运算(不允许的操作),这将导致编译错误// p = p + 1 // 这行代码会导致编译错误// 输出 x 的值和指针变量 p 的值t.Logf("x 的值:%d,指针变量 p 的值:%p", x, p)
}
在这个例子中,尝试进行指针运算 p = p + 1 会导致编译错误,因为在 Go 中不允许直接对指针进行加法或减法运算。
- string是值类型,其默认的初始化值为空字符串,而不是null
在 Go 中,string 是一种特殊的值类型,它代表不可变的字符序列。string 的默认初始化值是空字符串而不是 null。以下是一个示例:
package string_testimport "testing"// TestStringInitialization 是测试 string 初始化的单元测试函数
func TestStringInitialization(t *testing.T) {// 声明一个字符串变量 s,其默认初始化值为空字符串var s string// 输出字符串变量 s 的值t.Logf("字符串变量 s 的值:%q", s)
}
在这个例子中,s 是一个字符串变量,由于没有显式赋值,它的默认初始化值是空字符串。通过 %q 格式化符输出字符串时,如果字符串为空,会显示为空字符串而不是 null。
四、运算符
1、算数运算符
运算符 | 描述 | 示例 |
---|---|---|
+ | 加法 | a + b |
- | 减法 | a - b |
* | 乘法 | a * b |
/ | 除法 | a / b |
% | 求余 | a % b |
++ | 自增 | a++ 或 ++a |
– | 自减 | a– 或 –a |
Go语言没有前置的++,–(++a)
以下是一个使用算术运算符的简单示例:
package arithmetic_operatorsimport "fmt"func main() {// 定义两个整数变量a := 10b := 5// 加法sum := a + bfmt.Printf("加法结果:%d\n", sum)// 减法difference := a - bfmt.Printf("减法结果:%d\n", difference)// 乘法product := a * bfmt.Printf("乘法结果:%d\n", product)// 除法quotient := a / bfmt.Printf("除法结果:%d\n", quotient)// 求余remainder := a % bfmt.Printf("求余结果:%d\n", remainder)// 自增a++fmt.Printf("自增后的值:%d\n", a)// 自减b--fmt.Printf("自减后的值:%d\n", b)
}
2、比较运算符
运算符 | 描述 | 示例 |
---|---|---|
== | 相等 | a == b |
!= | 不相等 | a != b |
< | 小于 | a < b |
> | 大于 | a > b |
<= | 小于等于 | a <= b |
>= | 大于等于 | a >= b |
package comparison_operatorsimport "fmt"func main() {// 定义两个整数变量a := 10b := 5// 相等equal := a == bfmt.Printf("相等:%t\n", equal)// 不相等notEqual := a != bfmt.Printf("不相等:%t\n", notEqual)// 小于lessThan := a < bfmt.Printf("小于:%t\n", lessThan)// 大于greaterThan := a > bfmt.Printf("大于:%t\n", greaterThan)// 小于等于lessThanOrEqual := a <= bfmt.Printf("小于等于:%t\n", lessThanOrEqual)// 大于等于greaterThanOrEqual := a >= bfmt.Printf("大于等于:%t\n", greaterThanOrEqual)
}
3、用==比较数组
- 数组的维数必须相同。
- 数组中元素的个数必须相同。
- 数组中的每个元素都必须相等。
package testimport ("fmt""testing"
)func TestArrayComparison(t *testing.T) {// 定义两个数组array1 := [3]int{1, 2, 3}array2 := [3]int{1, 2, 3}array3 := [3]int{4, 5, 6}// 使用 == 比较数组equal1 := array1 == array2equal2 := array1 == array3// 输出比较结果fmt.Printf("array1 是否等于 array2:%t\n", equal1)fmt.Printf("array1 是否等于 array3:%t\n", equal2)
}
4、逻辑运算符
运算符 | 描述 | 示例 |
---|---|---|
&& | 逻辑与 | a && b |
|| | 逻辑或 | a || b |
! | 逻辑非 | !a |
func TestLogical(t *testing.T) {// 定义两个布尔变量isTrue := trueisFalse := false// 逻辑与andResult := isTrue && isFalsefmt.Printf("逻辑与结果:%t\n", andResult)// 逻辑或orResult := isTrue || isFalsefmt.Printf("逻辑或结果:%t\n", orResult)// 逻辑非notResult := !isTruefmt.Printf("逻辑非结果:%t\n", notResult)
}
5、位运算符
运算符 | 描述 | 示例 |
---|---|---|
& | 位与 | a & b |
| | 位或 | a | b |
^ | 位异或 | a ^ b |
<< | 左移 | a << b |
>> | 右移 | a >> b |
&^ | 位清空 (AND NOT) | a &^ b |
func TestBitwiseOperators(t *testing.T) {// 定义两个整数变量a := 5 // 二进制: 0101b := 3 // 二进制: 0011// 位与andResult := a & bfmt.Printf("位与结果:%d\n", andResult) // 0001 (1)// 位或orResult := a | bfmt.Printf("位或结果:%d\n", orResult) // 0111 (7)// 位异或xorResult := a ^ bfmt.Printf("位异或结果:%d\n", xorResult) // 0110 (6)// 左移leftShiftResult := a << 1fmt.Printf("左移结果:%d\n", leftShiftResult) // 1010 (10)// 右移rightShiftResult := a >> 1fmt.Printf("右移结果:%d\n", rightShiftResult) // 0010 (2)// 位清空 (AND NOT)clearResult := a &^ bfmt.Printf("位清空结果:%d\n", clearResult) // 0100 (4)
}
与其他主要变成语言的差异
- ** **&^按位置零
该操作符的使用方式是 a &^ b,它的作用是将 b 中为 1 的位在 a 中对应位置上清零。
func TestBitwiseClear(t *testing.T) {// 定义两个整数变量a := 5 // 二进制: 0101b := 3 // 二进制: 0011// 使用 &^ 按位清零result := a &^ b// 输出结果fmt.Printf("a &^ b 按位清零结果:%d\n", result) // 0100 (4)
}
五、循环
与其他主要变成语言的差异
GO语言仅支持循环关键字for
1. 基本的 for 循环:
// 基本的 for 循环for i := 1; i <= 5; i++ {fmt.Println(i)}
2. for range 循环:
func TestFor(t *testing.T) {// 使用 for range 遍历数组numbers := []int{1, 2, 3, 4, 5}for index, value := range numbers {fmt.Printf("索引:%d,值:%d\n", index, value)}// 使用 for range 遍历字符串message := "Hello, Go!"for index, char := range message {fmt.Printf("索引:%d,字符:%c\n", index, char)}
}
3. while 条件循环:
func TestFor01(t *testing.T) {// 模拟 while 循环counter := 1for counter <= 5 {fmt.Println(counter)counter++}
}
4. 无限循环:
func TestFor02(t *testing.T) {// 无限循环counter := 0for {fmt.Println("无限循环")counter++if counter == 3 {break // 终止循环}}
}
5.if条件
1. 基本的 if 语句:
// 基本的 if 语句
x := 10if x > 5 {fmt.Println("x 大于 5")
} else {fmt.Println("x 不大于 5")
}
2. if 语句的条件可以包含初始化语句:
// if 语句的条件包含初始化语句if x := 10; x > 5 {fmt.Println("x 大于 5")} else {fmt.Println("x 不大于 5")}
在这个例子中,if 语句的条件部分包含了初始化语句 x := 10,这个变量 x 只在 if 语句的作用域内有效。
3.多个 if 语句的嵌套
// 多个 if 语句的嵌套x := 10if x > 5 {fmt.Println("x 大于 5")if x > 8 {fmt.Println("x 大于 8")}} else {fmt.Println("x 不大于 5")}
与其他主要变成语言的差异
- condition 表达式结果必须为布尔值
在 Go 语言中,条件表达式的结果必须是一个布尔值。这意味着 if 和 for 等语句中的条件表达式必须评估为布尔类型,不能接受非布尔类型的值
// Go 语言中的条件表达式必须是布尔值
if x > 5 {// ...
}// 错误示例,编译时将会报错
if x {// ...
}
在上述错误示例中,x 是一个变量,但它的类型不是布尔类型,因此这个条件表达式会导致编译错误。相比之下,一些其他语言可能允许使用非布尔类型的值作为条件。
- 支持变量赋值
6.switch条件
与其他主要变成语言的差异
1.条件表达式不限制为常量或者整数;
func TestSwitch(t *testing.T) {var x interface{} = "hello"switch x.(type) {case int:fmt.Println("x 是一个整数")case string:fmt.Println("x 是一个字符串")default:fmt.Println("未知类型")}}
switch 语句的条件表达式可以是任意类型,不限制为常量或整数。这使得 switch 可以用于更复杂的条件判断,例如字符串、接口等类型。
2.单个 case 中,可以出现多个结果选项,使用逗号分隔;
func TestSwitch2(t *testing.T) {num := 2switch num {case 1, 2:fmt.Println("数字是1或2")case 3:fmt.Println("数字是3")default:fmt.Println("未知数字")}}
3.与C语言等规则相反,Go 语言不需要用break来明确退出一个 case;
func TestSwitch3(t *testing.T) {day := "Monday"switch day {case "Monday":fmt.Println("星期一")case "Tuesday":fmt.Println("星期二")default:fmt.Println("其他日子")}
}
4.可以不设定switch 之后的条件表达式,在此种情况下,整个 switch 结构与多个 if…else…的逻辑作用等同
func TestSwitch4(t *testing.T) {num := 2switch {case num > 5:fmt.Println("数字大于5")case num > 0:fmt.Println("数字大于0")default:fmt.Println("未知数字")}
}