基础语法和常用特性解析 | 青训营

243 阅读7分钟

这是我在青训营写的第一篇笔记,因为之前有学习过其他编程语言,过于基础的便没有过多研究,用笔记的形式记录自己的成长以及进行查漏补缺,希望能不断进步。

一、

var(声明变量), const(声明常量), type(声明类型) ,func(声明函数)

  • 开头package xxx 例:package main

  • import声明(导入包) 例:import "fmt"

  • 不存在分隔符";"

  • {不能单独在一行 ,例:可以func main() {

  • Go源文件以“go”为扩展名

  • Go应用程序的执行入口是main()函数

  • Go语言严格区分大小写

  • Go编译器是一行行进行编译的,我们最好一行就写一条语句,不能把多条语句写在同一行,否则报错

  • Go语言定义的变量或者import的包如果没有使用到,代码就不能编译通过

  • 大括号是成对出现的,缺一不可

二、

1.变量

/*var name string   
var age int         
var m bool */       
​
var name = "tom"
var age =20
var b =ture
​

/类型可舍去/

var(
    name string
    age int
    b bool
)

/可统一写在()内/

//前括号里为参数,后括号里为返回值

func getNameAndAge()  (string , int){
​
        return "老郭" , 30
​
}

/* ···+enter 代码区块快捷键 **/

1.1 变量的作用域

根据变量定义位置的不同,可以分为以下三个类型:

  • 函数内定义的变量称为局部变量
  • 函数外定义的变量称为全局变量
  • 函数定义中的变量称为形式参数

2.常量

func main(){
    const PI float64 = 3.14
    const PI2 = 3.1415 //可以省略类型
}
2.1 定义常量

const:定义常量的关键字

constantName:常量名称

type:常量类型(可省略)

value:常量的值

3.字符串类型的做索引

func f3(){
    //key:value
m:=make(map[string]string,0)
m["name"]="tom"
m["age"]="20"
m["email"]="xgaxz@gmail.com"
for key,value:= range m{
    fmt.printf("%v:%v",key,value)
    }
​
}

4.map及map的遍历

4.1代码案例
    m1:=make(map[stirng]string)
    m1["name"]="tom"
    m1["age"]="20"
    m1["email"]="tom@gmail.com"
​
    fmt.printf("m1:%v\n",m1)
​
    m2:=map[string]string{
        "name":"kite",
        "age""20",
        "email":"kite@gmail.com"
​
}

/两种格式 /

func test01(){
    var m1=map[string]string("name:""tom","age":"20","tom@gmail.com")
    var k1="name"
    var k2="age1"
    v,ok:=m1[k1]
    fmt.Printf("v:%v\n",v)
    fmt.Printf("ok:%v\n",ok)
    fmt.Println("----------")
    v,ok = m1[k2]
    fmt.printf("v:%v\n",v)
    fmt.Printf("ok:%v\n",ok)
}
4.2

/15行代码这有两部分,a对应的value返回两个值,如果成功取到则赋值给v,第二部分是要判断的条件/

package main(){
import(
    "fmt"
)
func main(){
    var m map[string]int
    //m=make(map[string]int,100)
    m=map[sting]int("a":3,"b":6)
    m["c"]=1
    m["a"]=3
    fmt.Println(m["a"])
    delete(m,"a")
    fmt.Println(m["a"])
    
    if v,exist:=m["a"];exist{
        fmt.Println(v)
    }else{
        fmt.Println("map中不存在a这个key")
    }
    for k,v:=range m{
        fmt.Println(k,v)
    }
}
}
4.3

Go语言中 map的定义语法如下:

map[KeyType]ValueType
​

其中,

  • KeyType:表示键的类型。
  • ValueType:表示键对应的值的类型。
4.4判断某个键是否存在

Go语言中有个判断map中键是否存在的特殊写法,格式如下:

value, ok := map[key]
4.5 for range

可以使用for range遍历map

5.切片(slice)

以下是切片的结构定义:

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}
  • Data 是指向数组的指针
  • Len 是当前切片的长度
  • Cap 是当前切片的容量,即Data数组的大小

image.png

image.png

6.defer

1.关键字defer用来注册延迟调用,调用直到return前才被执行

2.类似栈,多个defer语句,先进后出

3.defer语句中的变量,在defer声明时便决定了。

7.init函数

1.不被其他函数调用,先于main函数自动执行 //加粗 ctrl+b

2.无参数,无返回值

3.每个包可以有多个init函数,包的每个源文件也可以有多个init函数(同一个包的init执行顺序,golang没有明确定义)

4.不同包的init函数按照包导入的依赖关系决定执行顺序

8.高阶函数

8.1

//11行代码左括号里为参数,右边返回值,此时为返回一个函数

package main
​
import "fmt"
func add(x int,y int)int{  
    return x+y
}
func mul(x int,y int)int{
    return x-y
}

func cal(operator string) func(int,int)int{
    switch operator{
        case "+":
            return add
        case "-":
            return mul
        default:
            return nil
    }
}
​
func main(){
    r:=cal("+")
    f:=r(1,2)
    fmt.Printf("the result is %v\n",f)
}
8.2

当有多个值返回的情况。 在声明返回值类型时,可以不指定名称,也可以指定名称

func Fun1(arg1 T, arg2 T)(T, T){
  ...
  return r1, r2
}
8.3

函数也可以没有返回值,这个时候就无需 return 关键字。例如: main() 入口函数、 init() 初始化函数。

以下为一个有参数无返回值的情况:

//13行代码参数的赋值方式不同

package main
 
import "fmt"
 
func main() {
    sayNum(1)
    sayNum2(2, 3)
    sayNum2(4, 5)
}
 

func sayNum(a int) {
    fmt.Println("a=", a)
}
func sayNum2(a int, b int) {
 
    fmt.Printf("a=%d\n b=%d\n", a, b)
}
func sayNum3(a, b int) {
 
    fmt.Printf("a=%d\n b=%d\n", a, b)
}
8.4

//14行代码 --这里是三个参数

//18行--故从这里传三个参数

package main
​
import "fmt"func add(x, y int) int {
    return x + y
}
​
func mul(x, y int) int {
    return x * y
}
​
func calc(x, y int, op func(int, int) int) int {
    return op(x, y) 
}
​
func main() {
    res := calc(10, 20, add)
    fmt.Println(res)  // 30
    resP := calc(10, 20, mul)
    fmt.Println(resP)  // 200
}
​

9.os模块

image.png

image.png

10.ioutil包

10.1读取

image.png

/第一句是读取,第二句为上传/

10.2读取(打开文件的方式)

image.png

//打开文件后要关闭,即defer f.close()这句

10.3读取目录

image.png

/ (”.“)...v为单个文件,v为文件目录,依次输入单个文件/

10.4写文件

image.png

10.5创建临时文件

(官网)

image.png

11.bufio

带缓冲的写入

image.png

image.png

12.json

//shift+tab 回退一个tab

image.png 把对象转变为一个二进制的流(byte切片)因为只有把它转为一个二进制流之后才可以执行i/o的存储或者是网络的传输,因为写在磁盘里面的或者网络传输的本质上都是一个二进制流,而不是一个结构体。所以需要把结构体转变为二进制流。

12.1序列化

最后打印是用到字符串(即这个byte字节流转换为string类型)

12.2反序列化

将它反序列化时声明一个c2结构体用来承接,需要一个取地址,因为在unmarshal内部给成员变量赋值,必须传指针,否则这个修改仅在函数内部生效而对外部结构体不影响。

字节跳动的sonic库,更快速,另外引用第三方库,需要配置一下 。

image.png

13.命名规范

go中根据首字母的大小写来确定可以访问的权限。

无论是方法名、常量、变量名还是结构体的名称,若首字母大写,则可以被其他的包访问;若首字母小写,则只能在本包中使用。

即首字母大写是公有的,首字母小写是私有的。

14.注释

单行注释的格式如下所示

//单行注释

多行注释的格式如下所示

/* 第一行注释 第二行注释 … */

15.指针

  • 对变量进行取地址操作使用&操作符,可以获得这个变量的指针变量。
  • 指针变量的值是指针地址。
  • 对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值。

16.数据类型转换

由于Go语言不存在隐式类型转换,因此所有的类型转换都必须显式的声明:

valueOfTypeB = typeB(valueOfTypeA)

类型 B 的值 = 类型 B(类型 A 的值)

示例:

a := 1.0 b := int(a)

17.字符串格式化时常用动词及功能

%v按值的本来值输出
%+v在 %v 基础上,对结构体字段名和值进行展开
%#v输出 Go 语言语法格式的值
%T输出 Go 语言语法格式的类型和值
%%输出 % 本体
%b整型以二进制方式显示
%o整型以八进制方式显示
%d整型以十进制方式显示
%x整型以十六进制方式显示
%X整型以十六进制、字母大写方式显示
%UUnicode 字符
%f浮点数
%p指针,十六进制方式显示

参考课程地址:

走进 Go 语言基础语法

golang的json序列化

golang入门到项目实战

golang之map详解