Go_0
本节记录基本语法结构
0. 应用程序入口
- 必须是main包:package main
- 必须是main方法:func main()
- 文件名不一定是main.go
1. 退出返回值
- Go中的main函数不支持任何返回值
- 通过os.Exit来返回状态
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("Hello world!")
//os.Exit(0) //正常退出
os.Exit(-1) //非正常退出
}
2. 获取命令行参数
- main函数不支持传入参数:func main(
arg []string) - 在程序中直接通过os.Args获取命令行参数
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) > 1 {
fmt.Println("--->", os.Args[1])
}
}
3. 编写测试程序
- 源码文件以_test结尾:xxx_test.go
- 测试方法名以Test开头:func TestXXX(t *testing.T){…}
package test
import "testing"
func TestFirstTry(t *testing.T) {
t.Log("First Test Try")
}
在测试文件中常使用t.Log(“…”),而不用fmt.Println(“…”)
4. 变量
先看一个斐波那契数列的案例
package fib
import (
"fmt"
"testing"
)
func TestFibList(t *testing.T) {
var a = 1
var b = 1
fmt.Print(a)
for i := 0; i < 5; i++ {
fmt.Print(" ", b)
tmp := a
a = b
b = tmp + a
}
fmt.Println()
}
变量声明:
// 1 常用于变量的声明,全局或外部的变量
var a int = 1
var b int = 2
// 2
var (
a int = 1
b int = 2
c = 3
d = 4
)
// 3
a := 1
b := 2
- 多变量赋值
func TestExchange(t *testing.T) {
a := 1
b := 2
a, b = b, a
t.Log(a, b)
}
5. 常量
- 快速设置连续值
package constant_test
import "testing"
const (
Monday = 1 + iota
Tuesday
Wednesday
)
func TestConstant(t *testing.T) {
t.Log(Monday, Tuesday, Wednesday)
}
运行结果:1 2 3
- 也可以进行类似状态位的设置(与运算)
package constant_test
import "testing"
const (
// 可以进行状态位的设置
Readable = 1 << iota //0001
Writable // 0010
Executable // 0100
)
func TestConstant1(t *testing.T) {
a := 7 //0111
b := 1 //0001
t.Log(a&Readable == Readable, a&Writable == Writable, a&Executable == Executable)
t.Log(b&Readable == Readable, b&Writable == Writable, b&Executable == Executable)
}
6. 基本数据类型
- bool
- string
- int int8 int16 int32 int64
- uint uint8 uint16 uint32 uint64 uintptr
- byte // uint8
- rune // int32
- float32 float64
- complex64 complex128
go中的int类型大小随操作系统的位数确定,32位OS就是int32四字节,64位OS就是int64八字节
类型转化
- Go不允许隐式类型转换
- 别名和原有类型也不能进行隐式类型转换
package type_test
import "testing"
type MyInt int64
func TestImplicit(t *testing.T) {
var a int32 = 1
var b int64
// 低精度转高精度也必须需要显式转换
b = int64(a)
var c MyInt
// 自定义类型也需要显示转换
c = MyInt(a)
t.Log(a, b, c)
}
类型预定义值
- math.MaxInt64
- math.MaxFloat64
- math.MaxUint32
7. 指针
- 不支持指针运算
- string是值类型,默认初始化值是空字符串,不是nil
func TestPoint(t *testing.T) {
a := 1
aPtr := &a
t.Log(a, aPtr)
t.Logf("%T %T", a, aPtr)
}
func TestString(t *testing.T) {
var s string
t.Log("*" + s + "*")
t.Log(len(s))
}
8. 运算符
和其他语言基本无差,仅列出有区别的部分
- 没有前置的++,--(++a)
用==比较数组
- 相同维数且含有相同个数元素的数组才可以进行比较
- 每个元素都相同才相等
func TestOperator(t *testing.T) {
a := [...]int{1, 2, 3, 4}
b := [...]int{1, 2, 3, 5}
// c := [...]int{1, 2, 3, 4, 5}
d := [...]int{1, 2, 3, 4}
e := [...]int{1, 2, 4, 3}
t.Log(a==b) // 元素不同,false
// t.Log(a==c) // 个数或维数不同,直接编译错误
t.Log(a==d) //完全一致,true
t.Log(a==e) // 4,3位置不同,false
}
位运算符
- &^ 按位清零:右操作位是1开启清零,右操作位是0则不操作
- 1 &^ 0 -> 1
- 1 &^ 1 -> 0
- 0 &^ 1 -> 0
- 0 &^ 0 -> 0
- 0111 &^ 0001 -> 0110
const (
// 可以进行状态位的设置
Readable = 1 << iota
Writable
Executable
)
func TestBitClear(t *testing.T) {
a := 7 // 0111
t.Logf("%b", a &^ Readable) // 111 &^ 001 -> 110
t.Logf("%b", a &^ Writable) // 111 &^ 010 -> 101
t.Logf("%b", a &^ Executable) // 111 &^ 100 -> 011
}
其实是玩了一个优先级差,利用优先级省略掉了()
所谓a&^b相当于a&(^b),就是先按位取反,再做与运算,达到按位清零的效果
9. 循环和条件
循环
- go中的循环只支持for
- for可以不写括号
while条件循环
n := 0
for n < 5 {
n++
fmt.Println(n)
}
无限循环while(true)
n := 0
for {
...
}
条件if
- 同样可以不写括号
//和其他编程语言差不多
if condition {
//
} else {
//
}
if condition {
//
} else if condition {
//
}
- 支持变量赋值
// 主要差别,只要是和go的多返回值配合使用
if var declaration; condition {
//
}
//例子
func TestIfMultiSce(t *testing.T) {
if v,err := someFun(); err == nil {
t.Log("正常操作")
} else {
t.Log("函数执行有错误")
}
}
条件switch
- 条件表达式不限制为常量或者整数
- 单个case中,可以出现多个结果选项,使用逗号分割
- 与C,Java等规则相反,go不需要break来明确推出一个case
- 可以不设定switch之后的条件表达式,在此种情况下,真个switch和ifelse的逻辑相同
func TestSwitch(t *testing.T) {
switch os := runtime.GOOS; os {
case "windows", "linux":
fmt.Println("--Windows or Linux--")
default:
fmt.Println(os)
}
}
下面switch与ifelse等同
func TestSwitchEquIfElse(t *testing.T) {
Num := 5
switch {
case 0 <= Num && Num <= 3:
fmt.Println("0-3")
case 4 <= Num && Num <= 6:
fmt.Println("4-6")
case 7 <= Num && Num <= 9:
fmt.Println("7-9")
}
}