Go 编程基础

一、Go 开发环境搭建

 暂无

二、Go 基础知识

 1、Go内置关键字(25个均为小写)

break    default    func    interface    select

case    defer    go    map    struct

chan    else    goto    package    switch

const    fallthrough    if    range    type

continue    for    import    return    var

2、Go注释方法

//  :  单行注释

/*  */  :  多行注释

3、可见性规则

在Go语言中,使用 大小写 来决定 常量、变量、类型、接口、结构、函数 是否可以被外部包所调用

根据约定,函数名首字母小写即为private

函数名首字母大写即为public

4、package别名

 

5、Go代码主要结构

// 当前程序的包名
package main

// 导入其它的包 ———— 导入后,如不使用会编译错误
import "fmt"
//或可以采用 组 的方式进行多个包的引入。在声明多个常量、全局变量、一般类型(非接口、非结构)时也可以采用此种方式
import (
  "fmt"
  "oi"
) // 常量的定义 const PI = 3.14 // 全局变量的声明与赋值 var name = "gopher" // 一般类型声明 type newType int // 结构的声明 type gopher struct{} // 接口的声明 type golang interface{} // 由 main 函数作为程序入口点启动 func main() { std.Println("Hello world!你好,世界!") }

三、类型与变量

 1、Go基本类型

  (值类型)布尔型:bool

    -长度:1字节

    -取值范围:true,false

    -注意事项:不可以用数字代表true或false

 

  (值类型)整型:int/uint

    -根据运行平台可能为32位或64位

  -8位整型:int8/uint8

    -长度:1字节

    -取值范围:-128~127 / 0~255

    -字节型:byte(uint8别名)

  -16位整型:int16/uint16

    -长度:2字节

    -取值范围:-32768~32767 / 0~65535

  -32位整型:int32(rune)/uint32

    -长度:4字节

    -取值范围:-2^32/2~2^32/2-1 / 0~2^32-1

  -64位整型:int64/uint64

    -长度8字节

    -取值范围:-2^64/2~2^64/2-1 / 0~2^64-1

  -浮点型:float32/float64

    -长度:4/8字节

    -小数位:精确到7/15小数位

 

  (值类型)复数:complex64/complex128

    -长度:8/16字节

    -足够保存指针的32位或64位整数型:uintptr

 

  (值类型)数组类型:array

 

  (值类型)结构体:struct

 

  (值类型)字符串型:string

 

  (引用类型)切片:slice

 

  (引用类型)哈希表:map

 

  (引用类型)哈希表:map

 

  (接口类型)接口:inteface

  

  (函数类型)函数:func

 

2、变量的声明与赋值

  单个变量的声明与赋值

    - 变 量 的 声 明 格 式 : var < 变 量 名 称 > < 变 量 类 型 >

    - 变 量 的 赋 值 格 式 : < 变 量 名 称 > = < 表 达 式 >

    - 声 明 的 同 时 賦 值 : var < 变 量 名 称 > [ 变 量 类 型 ] = < 表 达 式 >

     

   多个变量的声明与赋值

    -全 局 变 量 的 声 明 可 使 用 var()  的 方 式 进 行 简 写

    -全 局 变 量 的 声 明 不 可 以 省 略 var , 但 可 使 用 并 行 方 式

    -所 有 变 量 都 可 以 使 用 类 型 推 断

    -局 部 变 量 不 可 以 使 用 va r() 的 方 式 简 写 , 只 能 使 用 并 行 方 式

    

  变量的类型转换

    -Go中不存在隐式转换,所有类型转换必须显式声明

    -转换只能发生在两种相互兼容的类型之间

    -类型转换的格式:

      <ValueA>[:]= <TypeOfValueA>(<ValueB>)

      

四、常量与运算符

1、常量

  常量的定义

    -常量的值在编译时就已经确定

    -常量的定义格式与变量基本相同

    -等号右侧必须是常量或者常量表达式

    -常量表达式中的函数必须是内置函数

    

   常量的初始化规则

    -在定义常量组时,如果不提供初始值,则表示将使用上行的表达式

    -使用相同的表达式不代表具有相同的值

    -iota是常量的计数器,从0开始,组中每定义1个常量自动递增1

    -通过初始化规则与iota可以达到枚举的效果每遇到-个const关键字,iota就会重置为0

    

// 当前程序的包名
package main

// 导入其它的包
import (
    "fmt"
)

const (
    a = 'A'
    b = iota
    c = "B"  // 双引号里面可以是单个字符也可以是字符串,也可以有转义字符,如\n、\r等,对应go语言中的string类型。
    d = 'B'  // 单引号在go语言中表示golang中的rune(int32)类型,单引号里面是单个字符,对应的值为改字符的ASCII值。
    e = iota // 
    f = `iota` // 反引号中的字符表示其原生的意思,在单引号中的内容可以是多行内容,不支持转义。
)

// 由 main 函数作为程序入口点启动
func main() {
    fmt.Println(a)//65
    fmt.Println(b)//1
    fmt.Println(c)//B
    fmt.Println(d)//66
    fmt.Println(e)//4
}
View Code

 

2、运算符

  -Go中的运算符均是从左至右结合的

  -其优先级从高到低为

    -  ^ !    // ^2  为一元运算符

    - * / % << >> & &^

    - + - | ^    // 1 ^ 2 为二元运算符

    - == != < <= >= >

    - <-

    - &&

    - ||

  -运算符含义

  ^    //为两种情况:^作一元运算符表示是按位取反,包括符号位在内;

       //^作二元运算符就是异或,包括符号位在内,相同为0,不相同为1(即1^1 =0, 0^0=0,1^0=1,0^1=1 ; 示例:0001 0100 ^ 0000 1111 = 0001 1011 故 20 ^ 15 =27)

  !    //取反

 

  *    //相乘

  /    //相除

  %    //求余

  <<     //左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。

  >>    //右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。

  &    //按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。

  &^    //将运算符左边数据相异的位保留,相同位清零。此运算符特点:1、如果右侧是0,则左侧数保持不变;2、如果右侧是1,则左侧数一定清零。

  

  +    //相加

  -    //相减

  |    //按位或运算符"|"是双目运算符。其功能是参与运算的两数各对应的二进位相或

  

  ==    //检查两个值是否相等,如果相等返回 True 否则返回 False。

  !=    //检查两个值是否不相等,如果不相等返回 True 否则返回 False。

  <    //检查左边值是否小于右边值,如果是返回 True 否则返回 False。

  >    //检查左边值是否大于右边值,如果是返回 True 否则返回 False。

 

3、指针

  -Go虽然保留了指针,但与其它编程语言不同的是,在Go当中不支持指针运算以及“->”运算符,而直接采用“.”选择符来操作指针目标对象成员

  -操作符“&”取变量地址,使用“*”通过指针间接访问目标对象

  -默认值为 nil 而非 NULL

 

4、递增递减语句

  -在Go当中, ++与--是作为语句而并不是作为表达式

 

五、控制语句

1、判断语句:if语句

  -条件表达式没有括号

  -支持一个初始化表达式(可以是并行方式)

  -左大括号必须和条件语句或else在同一行

  -支持单行模式

  -初始化语句中的变量为block级别,同时隐藏外部同名变量

      

 

2、循环语句:for语句

  -Go只有for一个循环语句关键字,但支持3种形式

  -初始化和步进表达式可以是多个值

  -条件语句每次循环都会被重新检查,因此不建议在条件语句中使用函数,尽量提前计算好条件并以变量或常量代替

  -左大括号必须和条件语句在同一行

      

 

3、选择语句:switch语句

  -可以使用任何类型或表达式作为条件语句

  -不需要写break,一旦条件符合自动终止

  -如希望继续执行下一个case,需使用fallthrough语句

  -支持一个初始化表达式(可以是并行方式),右侧需跟分号

  -左大括号必须和条件语句在同一行 

      

 

4、跳转语句:goto、break、continue

  -三个语法都可以配合标签使用

  -标签名区分大小写,若不使用会造成编译错误

  -Break与continue配合标签可用于多层循环的跳出;区别为:break操作是跳出当前循环,continue是跳过本次循环

  -Goto是调整执行位置,与其它2个语句配合标签的结果并不相同

    

 

六、数组 array

1、数组Array

  -定义数组的格式:var <varName> [n] <type>,n>=0         // var a [2]int = {0,1} 

  -数组长度也是类型的一部分,因此具有不同长度的数组为不同类型;  //例子:var a [2]int      var b [1]int   这两个数组不是同一类型

  -注意区分指向数组的指针和指针数组

  -数组在Go中为值类型数组之间可以使用==或!=进行比较,但不可以使用<或>

  -可以使用new来创建数组,此方法返回一个指向数组的指针

  -Go支持多维数组

 

七、切片 slice

1、切片Slice

  -其本身并不是数组,它指向底层的数组

  -作为变长数组的替代方案,可以关联底层数组的局部或全部

  -为引用类型

  -可以直接创建或从底层数组获取生成

  -使用len()获取元素个数,cap()获取容量

  -一般使用make()创建

  -如果多个slice指向相同底层数组,其中一个的值改变会影响全部

 

  -make([]T, len, cap)

  -其中cap可以省略,则和len的值相同

  -len表示存数的元素个数,cap表示容量

 

2、Reslice

  -Reslice时索引以被slice的切片为准

  -索引不可以超过被slice的切片的容量cap0值

  -索引越界不会导致底层数组的重新分配而是引发错误

 

3、Append

  -可以在slice尾部追加元素

  -可以将一个slice追加在另一个slice尾部

  -如果最终长度未超过追加到slice的容量则返回原始slice

  -如果超过追加到的sIice的容量则将重新分配数组并拷贝原始数据

 

八、map

  -类似其它语言中的哈希表或者字典,以key-value形式存储数据

  -Key必须是支持==或!=比较运算的类型,不可以是函数、map或slice

  -Map查找比线性搜索快很多,但比使用索引访问数据的类型慢100倍

  -Map使用make0创建,支持:这种简写方式

 

  -make([keyType]valueType,cap),cap表示容量,可省略

  -超出容量时会自动扩容,但尽量提供一个合理的初始值

  -使用len()获取元素个数

 

  -键值对不存在时自动添加,使用delete0)删除某键值对

  -使用 for range 对map和slice进行迭代操作

 

九、函数 function

1、函数function

  -Go 函数 不支持 嵌套重载默认参数;但是支持:无需声明原型、不定长度变参、多返回值、命名返回值参数匿名函数、闭包

  -定义函数使用关键字 func,且左大括号不能另起一行

  -函数也可以作为一种类型使用

 

2、defer

  -其执行方式类似其它语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行(后定义,先调用)

  -即使函数发生严重错误也会执行

  -支持匿名函数的调用

  -常用于资源清理、文件关闭、解锁以及记录时间等操作

  -通过与匿名函数配合可在return之后修改函数计算结果

  -如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已经获得了拷贝,否则则是引用某个变量的地址

 

  -Go 没有异常机制,但有 panic/recover模式来处理错误

  -Panic 可以在任何地方引发,但recover只有在defer调用的函数中有效

 

 

十、结构 struct

1、结构struct

  -Go 中的struct与C中的struct非常相似,并且Go没有class

  -使用 type<Name>struct{} 定义结构,名称遵循可见性规则

  -支持指向自身的指针类型成员

  -支持匿名结构,可用作成员或定义成员变量

  -匿名结构也可以用于map的值

  -可以使用字面值对结构进行初始化

  -允许直接通过指针来读写结构成员

  -相同类型的成员可进行直接拷贝赋值

  -支持 ==与!=比较运算符,但不支持>或<

  -支持匿名字段,本质上是定义了以某个类型名为名称的字段

  -嵌入结构作为匿名字段看起来像继承,但不是继承

  -可以使用匿名字段指针

 

十一、方法 method

1、方法method

  -Go 中虽没有class,但依日有method

  -通过显示说明receiver来实现与某个类型的组合

  -只能为同一个包中的类型定义方法

  -Receiver可以是类型的值或者指针

  -不存在方法重载

  -可以使用值或指针来调用方法,编译器会自动完成转换

  -从某种意义上来说,方法是函数的语法糖,因为receiver其实就是方法所接收的第1个参数(Method Value vs.Method Expression)

  -如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法

  -类型别名不会拥有底层类型所附带的方法

  -方法可以调用结构中的非公开字段

 

十二、接口 interface

1、接口interface

  -接口是一个或多个方法签名的集合

  -只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示声明实现了哪个接口,这称为 Structural Typing

  -接口只有方法声明,没有实现,没有数据字段

  -接口可以匿名嵌入其它接口,或嵌入到结构中

  -将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针

  -只有当接口存储的类型和对象都为nil时,接口才等于nil

  -接口调用不会做receiver的自动转换

  接口同样支持匿名字段方法

  -接口也可实现类似OOP中的多态

  -空接口可以作为任何类型数据的容器

 

十三、反射 reflection

 

十四、并发 concurrency

 

十五、项目与坑

 

十六、其他

 

posted @ 2024-02-22 11:19  青砖黛瓦  阅读(59)  评论(0编辑  收藏  举报