Golang 学习:基础通关 | 青训营笔记

156 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

从新开始

第一天

  • 运行程序 go run xx.go
  • 编译程序 go build xx.go 这里有些需要注意的地方,主程序的包 package 必须是main ,其他的包名应该是目录名,同一目录同包名

在程序被划分为多个模块的时候,可以使用 go run main.go xx1.go ... 这种方式来运行或者编译多个程序文件;

第二天

  • 变量声明: var s1,s2 *int // 声明了两个整型指针变量; 批量声明 :
    var(
        s1 int
        s2 string
        d []float64
        f func() bool
        e struct {
          x int
        }
    )

可以明显看出go的类型定义有明显的后置类型声明的形式,同时可以将声明多个指针,和c系列的指针不同的是*要放在 类型之前, intptr 整型指针得是 *int

  • 变量初始化: s:=1 这种简化声明初始化只能在函数内部的进行局部声明; 也可以在声明结束后再行初始化 s =1 另外使用 s1,s2=1,2 是可以多变量赋值; 使用 var vname [type] = value 的形式可以声明初始化变量,同时类型不一定要显式声明,go可以从初始化值推断类型;

第三天

  • 字符串类型是不可变的 修改字符串,在底层是生成了一个修改后的新字符串,字符串变量重新指向这个新的字符串对象;
  • bool 类型和 0,1是无关的,不能用来比较大小,同时两者之间是不可以之间转换的;
  • nil 是go当中的空类型,nil之间的比较行为是未定义的;
  • go 当中不支持隐式的类型转换,需要转化数据类型的时候要调用显示
  • make(map[string] int) 创建一个 string-int 映射的字典 或者说哈希表,在取 key的时候可以 v,flag:=m[key] 使用flag来判断flag是否为空;也就是容器中是否存在当前的关系映射;
  • 函数定义中的参数声明也是可以后置 func(a int, b int) int func(a,b int) int 声明的效果是一样的;同时go 支持多个返回值 func getkeyAndValue(m map[string]int, key string ) (v int, k string) 来返回对应的键值对,或者判断是否存在
  • go 当中的指针操作比较有限,主要是通过指针来修改指向对象的值;实现引用传递的效果,避免大对象值拷贝带来的不必要的开销;
  • range 是go 当中的关键字,对于数组类型,返回的第一个值是索引,第二个值是索引对应的元素值;如果不需要使用索引,可以使用 _ 下划线来放置不使用的值;
  • 结构体初始化
type user struct{
    name string
    password string
}
var a = user{"wang","123"} // 不显式指定数据域参数名称需要给出全部数据
var b = user{name:"zhang"} // 通过数据域名称来部分初始化
b.password = "123"

可以给结构体定义成员函数 :

func(u User) checkPassword(password string) bool{
    return u.password==password
}

声明一个带有状态检查的函数

func findUser(user []User,name string) (v *User,err error){
    for _,u range user{
        if u.name==name{
            return &u,nil
        }
    }
    return nil,error.New("not found")
}
u,err:=findUser([]User{{"wang","1234"}},"wang")
if eil!=nil{
    fmt.Println(err)
    return
}else{
    fmt.Println(u.name)
}

遍历一个流对象

    input := bufio.NewScanner(f)
    for input.Scan() {
        /* 每一行来进行处理 */
    }

基础时间操作

/* 基础的时间操作 */
now:=time.Now()
fmt.Println(now.Year(),now.Month(),now.Day())
/* 这里必须使用一下的格式化样板字符串来规范时间格式 */
fmt.Println(now.Format("2006-01-02 15:04:05"))
t:=time.Now()
/* 获取时间差 */
diff:=t.sub(now)
/* 以不同时间单位来显示当前的时间差 */
fmt.Println(diff.Minutes(),diff.Secondes())
/* 解析一个字符串表示的时间信息 */
t2, err:=time.Parse("2006-01-02 15:04:05","2022-05-07 14:42:33")

字符串解析和转换 常见的字符串和数字之间的转换在C++和Java里面都是常用的方法:

  1. Java的 包装类型.parseXXX系列,valueOf都提供了字符串到数值类型之间的转换;
  2. C++的 sting::to_string() 可以将数值类型转换为字符串;stoi,stol,stod,stof 可以将字符串解析为对应的数值类型;同时还可以借用字符串流来存入再次读取为对应的数据类型;
  3. 在golang 中使用 strconv 包中提供的我 Parsexxx 将字符串类型解析为数值类型,同时可以指定精度; 使用 Atoi() 转为整型 Itoa() 整型转字符串型 生成随机数
func GenerateRandInt(min, max int) int {
    rand.Seed(time.Now().Unix()) //随机种子
    return rand.Intn(max - min) + min
}
// rand.Intn(max int) 会生成0 ~ max 之间的整数;