1 Go 基本语法

1 变量

1.1 变量 – 声明

变量声明标准格式:var 变量名 变量类型
示例:var a int
var 语句可以定义在包或函数内。

a. 后置变量类型
b. 变量命名规则遵循驼峰命名法
c. 声明变量后,系统会自动赋予该类型零值
d. 声明但是未使用的变量会被视为错误

1.1.1 零值

  • 变量在定义时没有明确的初始化时会赋值为零值。
  • 数值类型为 0
  • 布尔类型为 false
  • 字符串为 “”

1.2 变量 – 初始化

变量定义可以包含初始值,每个变量对应一个。
变量从初始值中获得类型。

// 标准格式
var 变量名 变量类型 = 表达式
// 示例
var a string = “hello”
// 推导格式
var 变量名 = 表达式
// 示例
var a = “hello”

短声明变量

  • 在函数中, := 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。
  • 函数外的每个语句都必须以关键字开始( varfunc 、等等), :=结构不能使用在函数外。
// 短格式
变量名 := 表达式
// 示例
a := “hello”

1.3 变量 – 作用域

  • 全局变量作用域为整个包
  • 局部变量的作用域由花括号决定,任一变量的作用域仅在所处花括号内

1.4 变量 – 变量覆盖

package main

import "fmt"

func main() {
    a := 1
    fmt.Println(a)

    {
        a := 2
        fmt.Println(a)
    }

    fmt.Println(a)
}

编译结果:
1
2
1
package main

import "fmt"

func main() {
    a := 1
    fmt.Println(a)

    {
        a = 2
        fmt.Println(a)
    }

    fmt.Println(a)
}

编译结果:
1
2
2
package main

import "fmt"

func main() {
    a := 1
    a := 2

    fmt.Println(a)
}

编译报错

2 类型系统

2.1 类型系统 – 基本类型

基本类型.png

2.2 类型系统 – 基本类型转换

数值类型(byterune, intX, uintX, floatX)之间的转换需要通过类型强转来完成

var a int32 = 123
var b int64 = int64(a)

数值类型和string之间的转换通过 标准库strconv中提供的函数进行

// string 到 int
int, err := strconv.Atoi(string)

// string 到 int64
int64, err := strconv.ParseInt(string, 10, 64)

// int 到 string
string := strconv.Itoa(int)

// int64 到 string
string := strconv.FormatInt(int64, 10)

2.3 类型系统 – 引用类型

  • 特指 slice 、 map 、channel 三种类型
  • 引用类型具有更复杂的存储结构

2.4 类型系统 – 自定义类型

使用关键字 type 定义用户自定义类型

package main

func main() {
    // 基于基本类型创建自定义类型
    type MyInt int

    // 自定义结构体类型
    type MyStruct struct {
        a int
    }

    // 自定义函数类型
    type MyFunc func(int) int
}

3 指针

指针、变量和地址: 每个变量都有地址,指针的值就是地址

package main

import "fmt"

func main() {
    var cat int = 1
    var str string = "banana"

    var catPtr *int = &cat
    var strPtr *string = &str

    fmt.Printf("%p %p\n", catPtr, strPtr)
}

编译结果:
0xc00000a0a8 0xc000040230

3.1 指针 – 通过指针修改变量的值

package main

import "fmt"

func main() {
    // 准备两个变量,赋值1和2
    x, y := 1, 2

    // 交换变量值
    swap(&x, &y)

    // 输出变量值
    fmt.Println(x, y)

}

// 交换函数
func swap(a, b *int) {
    // 取a指针的值,赋给临时变量t
    t := *a
    // 取b指针的值,赋给a指针指向的变量
    *a = *b
    // 将a指针的值赋给b指针指向的变量
    *b = t
}

编译结果:
2 1

4 关键字

  • var和const:变量和常量的声明
  • package && import:引包
  • func:用于定义函数和方法
  • return:用于从函数返回
  • defer:在函数退出前执行
  • go:用于并行
  • select 用于选择不同类型的通讯
  • interface 用于定义接口
  • struct 用于定义抽象数据类型
  • break、case、continue、for、fallthrough、else、if、switch、goto、default:流程控制
  • chan:用于channel通讯
  • type:用于声明自定义类型
  • map:用于声明map类型数据
  • range:用于读取slice、map、channel数据

5 运算符

5.1 算术运算符

算术运算符.png

5.2 赋值运算符

赋值运算符.png

5.3 关系运算符

关系运算符.png

5.4 逻辑运算符

逻辑运算符.png

5.5 运算符 – 优先级

Go语言运算符优先级和结合性一览表.png

优先级值越大表示优先级越高
结合性指相同优先级在同一表达式中,且没有括号的时候,操作数计算的顺序

6 流程控制

6.1 流程控制 – 分支结构

// 1. 简单形式
if condition {
    // todo
}

// 2. 简单形式
if condition1 {
    // todo
} else if condition2 {
    // todo
} else {
    // default
}

// 3. 特殊写法,可以在if表达式之前添加一个执行语句,再根据变量值进行判断
if err := Connect(); err != nil {
    fmt.Println(err)
    return
}

6.2 流程控制 – 循环结构

// 完整形式
sum := 0
for i := 0; i < 10; i++ {
    sum += i
}

// 初始语句、条件表达式、结束语句可以有一个或多个为空
sum := 0
i := 0
for ; i < 10; i++ {
    sum += i
}

// 无线循环
for {
    sum++
    if sum > 100 {
        break
    }
}

不支持while
循环支持breakcontinue

6.3 流程控制 – switch

package main

import "fmt"

func main() {
    var a = "hello"
    switch a {
    case "hello":
        fmt.Println(1)
    case "world":
        fmt.Println(2)
    default:
        fmt.Println(0)
    }
}

编译结果:
1
package main

import "fmt"

func main() {
    var s = "hello"
    switch {
    case s == "hello":
        fmt.Println(1)
        fallthrough
    case s == "world":
        fmt.Println(2)
    default:
        fmt.Println(0)
    }
}

编译结果:
1
2

7 代码风格

  • 每行结束后不需要分号 ‘;
  • 大括号不能换行放置
if condition
{
    // todo
}
  • 自加、自减不再是一个操作符,而是一条语句
  • 变量或者 import 的包没有使用到,则编译报错
  • 可以安装gofmt工具,设置ide保存时自动格式化

你可能感兴趣的:(1 Go 基本语法)