> 文档中心 > Go语言学习教程(五)

Go语言学习教程(五)

一、常量概述

* 常量是一个固定值,在编译器就确定结果.声明时必须赋值且结果不可以改变.

* 因为常量在编译器就确定,可以防止程序运行过程中意外修改

* 常量关键字const

* 常量定义完可以不使用

* Go语言中常量定义没有明确语法要求,可以不全大写,驼峰即可.

* 很多内容可以定义成常量

    * 人名

    * 圆周率

    * 电话号

    * 等

二、常量定义

* 定义常量时如果不是必须指定特定类型,可以省略类型,使用默认类型,且数值类型常量(不定义类型)可以直接进行运算

* 常量的值可以是表达式,但是不允许出现变量

func main() {

const a string = "smallming"

const b = 123

const c = 3*2 + 5//不要指定类型

const d = 1.5//不要指定类型

fmt.Printf("%T %T",c,d)//int float

fmt.Println(c+d)//12.5

//下面这种方式是错误的

i := 3

const e = i*2 + 5 //const initializer i * 2 + 5 is not a constant

}

* 当定义多个常量时官方推荐的方式

const (

        a = 1

        b = 2

        c = true

    )

* 定义多常量时后一个常量如果没有赋值,与前一个常量值相同.

    * 第一个常量必须赋值

func main() {

    const (

        a = 1

        b

        c

    )

    fmt.Println(a,b,c)//输出:1 1 1

}

三、常量生成器

* 当一组常量都是数值类型,可以使用常量生成器iota指定这组常量按照特定规则变化

* iota起始值为0,每次增加1

func main() {

    const (

        a = iota

        b

        c

    )

    fmt.Println(a, b, c) //输出: 0 1 2

    const (

        d = iota << 1

        e

        f

    )

    fmt.Println(d, e, f) //输出:0 2 4

}

* 无论是否使用iota,一组常量中每个的iota值是固定的,iota按照顺序自增1

* 每组iota之间无影响

func main() {

    const (

        a = 5    //iota=0

        b = 3    //iota=1

        c = iota //iota=2

        d        //iota=3

    )

    fmt.Println(a, b, c, d) //输出5 3 2 3

    const (

        e = iota //iota=0

        f        //iota=1

        g = 10   //iota=2

        h        //iota=3

        i = iota //iota=4

        j        //iota=5

    )

    fmt.Println(e, f, g, h, i, j) // 0 1 10 10 4 5

}

四、变量地址

* 变量本质就是内存中一块数据的标记。把值存储到变量中实质是把值存储到内存中

* 每次对变量重新赋值就是在修改变量地址中的内容

* 在Go语言中可以通过 &+变量名 获取到变量地址值

* 重新创建一个非引用型变量(即使是把已有变量直接赋值给新变量)也会新开辟内存地址.

二、指针变量

* 指针变量指向一个值的内存地址

* 使用&+变量 返回值就是一个指针类型

* 使用var 变量名 *类型 声明指针类型变量

* 声明指针不会开辟内存地址,只是准备要指向内存某个空间,而声明变量会开辟内存地址,准备存放内容。所以指针类型变量都是把一个变量的地址赋值给指针变量

* 使用*+指针能够获取内存地址中的值.所以*+指针就和直接使用变量是相同的

* 应用指针可以实现多个地方操作同一个内存地址的值(在方法参数应用指针较多)

func main() {

    //创建变量

    a := 123

    var point *int

    point = &a //此时point和&a是相等的

    fmt.Println(point)

    *point = 3             //等价于a=3

    fmt.Println(*point, a) //*point和a是相当的

}

三、空指针

* 指针目的就是指向内存中一块地址

* 声明指针后指针不会指向任何内存地址,所以此时指针是空.在Go语言中空用nil表示

func main() {

    var a *int

    fmt.Println(a)        //输出:

    fmt.Println(a == nil) //输出true

}

四、new函数

* 可以通过new函数直接创建一个类型的指针:变量名:=new(Type)

* 使用new函数创建的指针已有指向,可以使用*指针对象进行赋值.

func main() {

    a := new(int)

    fmt.Println(a) //输出:指针地址

    *a = 123

    fmt.Println(*a) //输出:123

}

* 只声明的指针变量不能直接赋值。

五、条件判断if

* 在程序开发中经常需要判断.根据情况不同,程序执行的分支也不同.这个时候就可以使用if

* if在程序中代表如果,如果条件成立就执行,否则就不执行

* if的语法结构,在编译器中表达式两侧可以写小括号,但是通常省略

* 在if语法结构中所有表达式最终结果都是bool类型,true代表成立并执行对应代码

* 可以在if 表达式中声明变量,这个变量的范围只在if中能够使用

* 多个单独if使用时相互没有影响

func main() {

    score := 65

    if score >= 60 {

        fmt.Println("及格")

    }

    if score < 60 {

        fmt.Println("不及格")

    }

}

六、程序调试

* 程序调试,俗称:debug,通过特定的手段,一个语句一个语句的观察程序执行过程

* debug经常用在调错中,当结果不符合预期,代码又很多时,debug可以找出哪行出现问题

* 程序调试步骤

    * 在程序中某行前面单击出现红色圆形

    * 右键,选择Debug '文件名'

    * 通过点击按钮或使用快捷键选择:向下执行(F6),进入调用(F5),向上跳出(F7)观察程序

七、if ... else 结构

* if 可以单独使用也可以结合else使用,当满足互斥条件时使用if...else结构

* if..else结构中如果if成立执行if否则执行else

func main() {

    i := 59

    if i >= 60 {

        fmt.Println("及格")

    } else{

    fmt.Println("不及格")

    }

}

* if每种结构都可以相互嵌套

* 理论讲if可以很多层嵌套

* 当需要判断多个条件时使用if ... else if .... else结构

* 这个结构是一个整体.只要有一个条件成立后面的都不判断,立即结束

* else可以没有

* 改写嵌套代码,修改如下

func main() {

    score := 77

    if score >= 90 {

        fmt.Println("优秀")

    } else if score >= 80 {

        fmt.Println("良好")

    } else if score >= 70 {

        fmt.Println("中等")

    } else if score >= 60 {

        fmt.Println("及格")

    } else {

        fmt.Println("不及格")

    }

}