GO基础知识 | 青训营笔记

361 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

基础语法

数组

var a [5]int  //长度固定

切片slice

//用make创建切片,长度为2
s := make([]string,2)
s[0] = "a"
s[1] = "b"//append结尾追加
s = append(s,"c")
​
//copy(c,s),把s拷贝到c里面
c := make([]string,len(s))
copy(c,s)
​
//切片
fmt.Prinln(s[1:3])  //输出bc
s[1::]
s[:3]
//带值初始化,不用make
good := []string{"g","o","o","d"}

map

  • go中的map是完全无序的
//用make创建空map
m := make(map[string]int)
​
m["one"] = 1
m["two"] = 2
​
r,ok = m["one"]
​
//delete
delete(m,"one")
​
//带初始值构造
m := map[string]int{"one":1,"two":2}

range

//切片
nums := []int{2,3,4}   //不指定长度是切片
for i,data := range nums {
    
}
​
//map
m := map[string]int{"a","b","c"}
for k,v := m {
    
}

函数

func func_name(a int,b int)(ret1 int,ret2 int)

指针

  • go的传参默认是拷贝,所以想修改只能传指针
  • 不允许有指针运算
func add(a *int){
    *a += 1
}
​
//传入参数是结构体时不用解引用
func add(u *user){
    u.name = "eee"   //不用解引用
}

结构体

//声明
type user struct{
    name string
    age int
}
​
//初始化列表(type{...})
a := user{name:"wang",age:13}
b := user{"wang",13}
c := user{name:"wang"}  //加上成员变量可以只部分初始化
c.age = 10//传入结构体指针也不用解引用,而且能改变值
func updateAge(u user,a int){
    u.age = a
}
func newUpdateAge(u *user,a int){
    u.age = a
}
​
//匿名结构体对象
WiKi struct{
​
}//生成一个结构体实例化对象WiKi

结构体方法

type user struct{
    name string
    age int
}
​
func (u user) upAge(age int){ // 不带指针实际上是对结构的拷贝,不会修改调用的结构体
    u.age = age
}
​
func (u *user) netUpAge(age int){ //带指针能实现修改结构体
    u.age = age
}
​
func main(){
    //....
    u.upAge(10)
}

错误处理函数

func MyFunc()(v *user,err error){ //返回指针和error
    //...
    return &u,nil
    else{
        return nil,errors.Now("not found") //通过errors.Now()构建错误信息
    }
}
​
//错误判断
err != nil
//错误输出
fmt.Println(err)

字符串操作

  • `` 表示的字符串不转义,如字符串

    var s string = `"hello world"`   //这个字符串中含有双引号,不需要转义
    
a := "hello"   // 字符串是基础数据类型
strings.Contains(a,"ll")     //true
strings.Count(a,"l")         //2
strings.HasPrefix(a,"he")    //true
strings.HasSuffix(a,"llo")   //true
strings.Index(a,"ll")        //2
strings.Join([]string{"he","llo"},"-")  //he-llo
strings.Repeat(a,2)          //hellohello
strings.Replace(a,"e","E","-1") //hEllo
strings.Split("a-b-c","-")   //["a","b","c"]
strings.Tolower(a)           //hello
strings.TOUpper(a)           //HELLO
strings.TrimSuffix(a,"\n")   //将a中的后缀\n去掉
strings.Trim(a,"\n")         //将a中的\n去掉
len(a)                       //5
b := "你好"
len(b)                       //6   汉字大小为3//将字符串转为流
var data = strings.NewReader(`{"trans_type":"en2zh","source":"goods"}`)

字符串格式化

JSON格式

{}中是键值对
[]是值数组
"key":[{}]键值对的数组
  • 将结构体转为JSON格式
import(
    "encoding/json"
)
type userInfo struct {
    Name string
    Age int `json:"age"`  //自定义key的字符串
    Hobby []string
}
​
func main(){
    //结构体序列化
    a := userInfo{Name:"wang",Age:10,Hobby:[]string{"GO","C++"}}
    buf,err := json.Marshal(a)
    ...
    fmt.Println(buf) //[123 34 78...]   buf是一个[]byte
    fmt.Println(string(buf)) //{"Name":"wang","age":10,"Hobby":["GO","C++"]}
    
    //json反序列化
    var b userInfo
    json.Unmarshal(buf,&b)
}

时间处理

import(
    "time"
)
//获取当前时间
now := time.Now()
​
//构造时间
t := time.Data(2022,3,27,1,25,36,0,time.UTC)//年月日时分秒毫秒//获取时间
t.Year()
t.Month()
​
//格式化时间
fmt.Println(t.Format("2006-01-02 15:04:05"))  //用括号中的形式输出t//时间差
diff := t2.Sub(t1)
fmt.Println(diff) //1h5m0s
fmt.Println(diff.Minutes(),diff.Seconds()) //65 3900//解析时间,用前面的格式解析后面的时间
t3,err := time.Parse("2006-01-02 15:04:05","2022-3-27 01:25:36")
if err!=nil{
    panic(err)
}
​
//获取时间戳 Unix()
fmt.Println(now.Unix())

数字字符解析

import(
    "strconv"   //string convert
)
​
//64表示64位精度
f,_ := strconv.ParseFloat("1.234",64)
​
//10进制,64位
n,_ := strconv.ParseInt("111",10,64)
//0表示字符串的进制自己判断,64位
n,_ := strconv.ParseInt("0X111",0,64)
​
//strconv.Atoi("123")只能10进制
n,_ := strconv.Atoi("123")
s,_ := strconv.ItoA(123)

获取进程相关信息

os.Args   //进程的命令行参数//获取环境变量
os.Getenv("PATH")
​
//设置环境变量
os.Setenv("AA","value")
​
//通过子进程的形式启动其他程序,对应c语言中的linux接口exec
//grep命令从/etc/hosts文件中找"127.0.0.1"字符所在的行,并将输出通过CombinedOutput()输出到buf中
buf,err := exec.Command("grep","127.0.0.1","/etc/hosts").CombinedOutput()