(一)Go基础 | 青训营笔记

100 阅读4分钟

1 GO基础

1.1 GO语言特点

内存自动立即回收

1.2 语法特点

  1. 关键字package

Go语言的代码通过(package)组织,包类似于其它语言里的库(libraries)或者模块(modules)。一个包由位于单个目录下的一个或多个.go源代码文件组成,目录定义包的作用。每个源文件都以一条package声明语句开始,表示该文件属于哪个包,紧跟着一系列导入(import)的包,之后是存储在这个文件里的程序语句。

package main定义了一个独立可执行的程序,而不是一个库。

import导入其他要使用的包,常用的有fmt, math

  1. 变量声明

变量使用关键字var声明,可以不赋值,会有默认值。

具体类型可通过直接赋值隐式推导,也可以显式写出变量类型。

语句类型有如下几种:

//隐式推导
var a="hello,"
b := a + "world!"
var c = true
//显示声明
var d int =2
var e float64 //default 0
var f bool //default false
g := float32(e)
h := 1 //循环定义变量常用写法

可以合并声明变量

var a, b ="hello", 1

变量很多可以批量声明

var{
  ...
}
  1. 常量声明

常量使用关键字const声明,在定义时必须赋值

Go中常量没有确定的类型,会根据上下文自动确定类型

  1. 作用范围

包一级:所有这个包内的go文件均可使用

函数:

局部变量:写在循环,if-else,switch之后,仅此范围内使用

  1. 函数声明

函数使用关键字func声明,变量类型后置

func 函数名(参数名1 参数类型1, 参数名2 参数类型2) 返回值类型{
  ...
  return ...
}
​
//如果参数类型相同,可合并
func 函数名(参数名1, 参数名2 参数类型) 返回值类型{
  ...
  return ...
}

传入的参数是个拷贝,不能修改,若要修改就要使用指针

1.3 语句分支

1.3.1 语句风格
  1. 编辑器会自动进行格式化

包括下列提到的问题,就算使用了非默认写法,都会自动进行修改

  1. 分号
  • 换行不需要分号

书中说“Go语言不需要在语句或者声明的末尾添加分号,除非一行上有多条语句。“ Goland会自动格式化,分行,去除分号。

实际上,编译器会主动把特定符号后的换行符转换为分号,因此换行符添加的位置会影响Go代码的正确解析(译注:比如行末是标识符、整数、浮点数、虚数、字符或字符串文字、关键字breakcontinuefallthroughreturn中的一个、运算符和分隔符++--)]}中的一个)。

函数的左括号{必须和func函数声明在同一行上,且位于末尾,不能独占一行,而在表达式x + y中,可在+后换行,不能在+前换行(译注:以+结尾的话不会被插入分号分隔符,但是以x结尾的话则会被分号分隔符,从而导致编译错误)。

  • 在if,switch,for等后边加分号间隔不同语句
  1. 括号

    if、for、switch等不需要括号包含条件

1.3.2 流程控制
  1. 必须加大括号,即使只有一行
  2. if-else
  3. switch不需要加break就会退出

1.4 复合数据类型

  1. array

固定大小

  1. 切片
//definition
s := make([]type, size)
s := []type{values}
​
s = append(s, value) 

切片的底层实现是 长度+容量+指向数组的指针 在扩容时若容量不够,会进行扩容,所以需要重新赋值(第二行)

常用函数

copy(a, b) 在两个相同数据类型(不同精度也属于不同类型)的slice间将b的值复制给a

若 len(a) < len(b),仅复制len(a)的部分

若 len(a) > len(b),仅复制len(b)的部分

  1. map
//definition
mp := make(map[string]int)
//set value
mp["one"] = 1//if exits key
value, is_exist = mp["two"] //default value, bool//delete
delete(mp, "one")
  1. range

表示遍历。

对于一般数组,相较于C++或python的for char c:s或者for i in range(...),go的range既有index又有value。

for index, value := range nums{
    ...
}

遍历map,同时获得key和value

for key, value := range mp{
    ...
}
  1. 结构体
type struct_name struct{
  name1 type1
  name2 type2
}
​
//使用
var example struct_name

不能对struct进行range

1.5 常用包

  1. STRINGS
import{
  strings
}
​
//function name upper or lower case can be styled by ide 
//all substrings must use double quotation mark
strings.Contains(s, "substring") //bool
strings.Count(s, "substring") //int, count substring means can be multiple characters
strings.HasPrefix(s, "prefix") //bool
strings.HasSuffix(s, "subfix") //bool
strings.Index(s, "substring") //first index the substring begins
strings.Join([]string, "separator") //join the substring with separator
strings.Repeat(s, count) //strings a*count
strings.Replace(s, "old", "new", n) //replace the first n old with new
                                    // if n>=count(old) || n<0, replace all
strings.Split(s, "separator")//separate the string with separator
strings.ToLower(s) // total change to lowercase
strings.ToUpper(s) // total change to uppercase
len(s)//size
  1. JSON

想要能通过json包序列化处理的struct的成员命名需要首字母大写,后续字母大小写没有影响。不满足首字母大写的成员会在处理中自动忽略。

import{
  encoding/json
}
​
type userInfo struct {
  Name  string //ok
  name string //ignore
  Age   int `json:"age"` //here to change to age: when output fields not Age
  Hobby []string
}
​
​
buf, err := json.Marshal(a) //after marshal get []byte
string(buf) //need to force type conversion string to output fields
json.MarshalIndent(a, "prefix", "indent") //usually prefix := " ", indent := "\t"
/*
  {
  <prefix><indent>"a": 1,
  <prefix><indent>"b": 2
  <prefix>}
*/
​
json.Unmarshal(buf, &b)
  1. TIME
  2. STRCONV
  3. OS

3 实战

翻译

curlconverter.com/#go

oktools.net/json2go