02. Go语言程序结构

Go语言程序结构

一、Go语言程序元素

1). 标识符

  1. 标识变量、函数、自定义程序实体。
  2. 预定义标识符:
    1. 数据类型:
      • bool (true和false)、
      • byte、uint16、float32、float64、int、int8、int16、uint32、int32、int64、uint64、
      • string、uint、uint8、uintptr
    2. 内建函数名:append、cap、close、complex、copy、delete、imag、len、make、new、panic、print、println、real、recover;
    3. 其他标识符:iota、nil、_

_叫作空标识符,一般用在变量声明与包的导入中,例如 Go 语言程序中,若存在一个没有使用的变量a,那么编译时会报错,因为Go语言要求存在实体必须使用,所以可以加一句_=a这样的代码,这样Go语言编译器会认为使用了a变量,也就不会报错了,而实际上并没有对变量a做任何操作。程序初始化后空标识符就会被释放。

  1. 标识符以字母a~z(大小写均可)或下画线_开头,后面可以是多个字母、下画线和数字

Go语言不允许在标识符中使用标点符号,例如@、$、%等一系列符号

  1. 区分大小写

2). 关键字

  1. 静态编译型语言,只有简单的25个。
  2. 包导入声明:import package
  3. 程序实体声明与定义:var type func interface map struct chan const
  4. 流程控制:if continue for return go case goto switch select else break default defer fallthrough range
  5. 空接口:_

3). 字面量

值的一种标记

  1. 基础数据类型值的各种字面量
  2. 用户构造的自定义复合数据类型的类型字面量
  3. 复合数据类型的值的复合字面量

被用来构造类型 Struct Array Slice Map

4). 分隔符

  1. 括号:括号、中括号、大括号
  2. 标点分隔符:小数点、逗号、分号、冒号、省略号

Go 语言语句结尾不需要分号,如果一行有个多语句则需要,但是别这样写!

5). 运算符以及优先级


Go 运算符1.png
Go 运算符2.png
  1. 一元运算符优先级高于二元运算符
  2. 二元运算符之间也有优先级
  3. 优先级相同从左到右
  4. 括号的优先级永远最高

Go 运算符3.png
  1. ++ -- 是语句,不是表达式,没有优先级之说;
  2. Go 摒弃了C++的运算符重载

6). 注释

// 注释
/* 注释 */

/*
注释
 */

二、常量

  1. 编译期已知固定值不会改变。
  2. 可定义为常量的数据类型:
    • 数值:整型、浮点型、复数类型
    • 布尔值
    • 字符串
    • 等等
  3. 关键字 const
  4. 格式
const identifier [type] = value

const Pi = 3.1415926

// 指定明确类型
const Pi2 float32 = 3.1415926
const Return = true
const hello = "Let`s go"

Go 语言中可以省略类型说明,Go编译器可以智能判断值的类型。

// 显示定义
const h string = "hello"

// 隐式定义
const w = "world"
  1. Go支持超长的小数位数,如果指定了为特定类型,比如float32,则会自动缩短为32b;float64则为64b
  2. Go支持反斜杠\,可以作为跨行连接符,类似Linux中的Shell命令换行连接
const Pi = 3.1415\
            926\
            535
  1. 使用内置函数可以赋值给常量
const l = len("hello")

数字常量不需要考虑类型转换问题,但是如果将常量赋值给精度过小的数据变量而导致溢出的情况,编译期会报错。

1). 数字表示

Go语言的常量可以是十进制、八进制或者十六进制的常数

  1. 16进制,前缀0x或者0X0x7ea5 0X0123456789abcdef

  2. 8进制,前缀001234567 0665

  3. 10进制:无前缀

  4. 数字后缀

    • u或者U: 无符号 unsigned
    • l或者L: 长整型 long

后缀可以同时使用,顺序不限

3.14
0213
0x4b
0xFeeL
1234UL

2). 转义字符

  1. 使用反斜杠\表示转义字符

Go转义字符.png

3). 赋值

  1. 常见赋值写法
package main

import "fmt"

func main() {
    a := 20
    b := a
    fmt.Println(b)
    
    b += a
    b -= a
    b *= a
    b /= a
    b %= a
    b <<= a
    b >>= a
    b &= a
    b ^= a
    b |= a
}
  1. 并行赋值写法
const a, b, c = 1, 2, 3
const (
    d, e, f = 4, 5, 6
)

4). 枚举

  1. 枚举写法
const (
    Connected = 0
    Disconnected = 1
    Unknown = 2
)
  1. iota关键字
package main

import "fmt"

const (
    a = iota // a== 0
    b        // b == 1 ,隐式调用iota关键字,等同于 b = iota
    c        // c == 2, 实际等同于 c = iota
    d, e, f = iota, iota, iota // 同一行值相同,都是 3,此处不能写一个iota
    g = iota // g == 4
    h = "h"  // h == "h" 但是 iota递增为5
    i = h      // i == "h" 沿用上方的值,iota递增为6
    j = iota // j == 7
    k = iota + 50 // 可以参与表达式计算
)

const z = iota // 每个单独定义的常量中,iota会重置为0

func main() {
    fmt.Println(a, b, c, d, e, f, g, h, i, j, k, z)
    // 0 1 2 3 3 3 4 h h 7 58 0
}

三、变量

1). 变量的声明

  1. 声明格式:var identifier type
  2. 单独定义
var a int
  1. 同种类型多个变量可以定义在一行
var c, d bool
  1. 整体定义
var (
    e, f int
    g, h string
)
  1. 同时赋值
a, c, d, e, f, g, h = 1, true, true, 2, 3, "a", "b"
fmt.Println(a, c, d, e, f, g, h)
  1. 同时声明和赋值, 静态赋值
var i, j, k int = 1, 2, 3
  1. 交换变量的值
i, j = j ,i

i, j, k = k ,i, j
  1. 动态赋值
var a1, b1, c1 = 1, 2, 3

2). 局部变量的声明

  1. 函数体内 声明变量的简写形式
package main

import "fmt"

func main() {
    
    a := 1 // 等同于 var a = 1
    
    fmt.Println(a)
}

Go语言会自动判断类型

  1. 全局变量的定义不限定位置,可以定义但是不使用,但是局部变量定义后必须使用
package main

import "fmt"

func main() {

    fmt.Println(a)
}

var a = 2
  1. 当变量被声明但没有赋值时,它的值就是定义时指定类型的零值
    1. int为0
    2. float为0.0
    3. bool为false
    4. string为空字符串
    5. 指针为nil等

如果变量甚至没有指定类型,那么系统默认它为int型,值为0,所有变量在Go语言中都是需要初始化的。

  1. 命名规范:驼峰命名法, 常量全大写

  2. 变量的类型可以在运行时实现自动推断

package main

import (
    "fmt"
    "os"
)

// 获取环境变量中的值
var (
    HOME = os.Getenv("HOME")
    USER = os.Getenv("USER")
    GOROOT = os.Getenv("GOROOT")
)

func main()  {
    fmt.Println(HOME, USER, GOROOT)
}

3). 匿名变量

  1. Go语言支持函数返回多个值,但是如果只需要部分值,可以用空标识符 _ 接受
package main

import (
    "fmt"
)

// 返回值如果没有指定类型,会沿用后方参数定义的类型
func GetClass() (stuNum int, className, headTeacher string)  {
    return 49, "一班", "李四"
}

func main()  {
    stuNum, _, _ := GetClass()
    
    fmt.Println(stuNum)
}

4). init 函数

  1. Go 语言中,除了可以在全局声明中初始化实体,也可以在 init 函数中初始化。
  2. init函数是一个特殊的函数,它会在包完成初始化后自动执行,执行优先级比main函数高,并且不能手动调用init函数。
  3. 每一个源文件有且只有一个init函数,初始化过程会根据包的依赖关系按顺序单线程执行。

可以在开始执行程序之前通过这个函数来对数据进行检验与修复,保证程序执行时状态正常

package main

import (
    "fmt"
    "math"
)

var Pi float64

func init()  {
    // 在 init 函数中计算Pi的值
    Pi = 4 * math.Atan(1)
}

func main()  {
    DPi := Pi * Pi
    fmt.Println(Pi, DPi)
}

你可能感兴趣的:(02. Go语言程序结构)