第六届字节跳动青训营第一课学习Go基本语法 | 豆包MarsCode AI 刷题

48 阅读5分钟

Go语言基础语法

特点

  • 高性能,高并发
  • 语法简单
  • 丰富的标准库
  • 完整的工具链
  • 静态链接
  • 快速编译
  • 跨平台
  • 垃圾回收

基础语法-Hello World

//入口包的一部分
package main
// 导入标准库的fmt包,屏幕输入输出字符串格式化字符串
import {
    "fmt"
}
// 主函数
func main(){
    fmt.Println("Hello World")
}

基础语法-变量

  • 变量类型: int,float64,string,bool
  • 字符串可用加号拼接,可用==比较
  • 声明变量: var name = value,var name type = value,name:=value
  • 常量: const name = value,无确定类型

基础语法-if else

  • if condition { }条件无需括号,if后必须有大括号

基础语法-循环

  • 只有for循环,无括号,可以使用break,continue

基础语法-switch

  • 变量名不需要类型,switch后无需括号,case后无需break
  • 可以使用任意变量类型
  • 可以取代if else语句,switch后不加变量,在case后写条件语句,可以多个
func main() {
    a:= 1
    switch a{
        case 1:
        fmt.Println("1")
        case 2:
        fmt.Println("2")
        default: 
        fmt.Println("default")
    } 
    t:= time.Now()
    switch {
        case t.Hour() < 12:
        fmt.Println("before noon")
        default: fmt.Println("after noon")
    }
}

切片

  • 可变长度的数组
  • 创建切片:s:= make([]int,5)
  • 添加元素:s= append(s,1)
  • 拷贝数据:copy(s1,s2)
  • 切片操作:s[start:end]
func main() {
    s:= make([]int,3)
    s[0] = 1
    s[1] = 2
    s[2] = 3
    s=append(s,4)
    s2:= make([]int,len(s))
    copy(s2,s)
    fmt.Println(s2[1:3])
}

map

  • 类似java的hashmap,无序
  • 创建map:m:= make(map[string]int)
  • 添加元素:m["key"]=1
  • 读取:m["key"]
  • 判断是否存在:v,ok := m["key"]
  • 删除:delete(m,"key")
func main() {
    m:= make(map[string]int)
    m["a"]=1
    m["b"]=2
    v,ok := m["a"]
    fmt.Println(v,ok)
    delete(m,"a")
    m2:= map[string]int{"a":1,"b":2}
    fmt.Println(m2)
}

range

  • 可以用来遍历map和slice,类似java的foreach
  • 对于数组可返回下标和值
  • 对于map可返回key和value
func main() {
    nums := []int{1,2,3}
    sum := 0
    m:= map[string]int{"a":1,"b":2}
    for i,num:= range nums {
        sum += num
    }
    fmt.Println(sum)
    for k,v:= range m {
        fmt.Println(k,v)
    }
    for k:= range m {
        fmt.Println(k)
    }
}

函数

  • 返回变量类型后置func add(a,b int) int
  • 可以返回多个值func add(a,b int) (int,int)

指针

  • 对传入的参数进行修改,需要使用指针func add(a,b *int)
  • 调用时需使用&
func add(*a int) int {
    return *a+2
}
func main() {
    a:=1
    fmt.Println(add(&a))
}

结构体

  • 带类型的字段的集合
  • 初始化:使用结构体名称,对每个字段进行初始化,也可以部分
  • 使用.访问字段
  • 可作为参数传递,分为指针和非指针

结构体方法

  • 类似java中的类成员方法
  • 结构体可使用.访问该方法
  • 定义方法:func (s *Student) Print(age int) {}可以有带指针不带指针两种
type Student struct {
    name string
    age int
}
func (s *Student) Print(age int) {
    u.age+1
}
func main() {
    s:=Student{"zhangsan",18}
    fmt.Println(s.age)
}

错误处理

  • 在函数的返回值类型后添加error,表示该函数可能会返回错误,需要return errorerrors.New("错误信息")
  • 调用时需要用err:=接收返回值,需要判断错误,没有错误时才可以取真正的返回值
type Student struct {
    name string
    age int
}
func find(Students []Student,name string)(s *Student,err error){
    for _,v:=range Students{
        if v.name==name{
            return &v,nil
        }
    }
    return nil,errors.New("没有找到该学生")
}
func main(){
    var students = []Student{
        {"张三",18},
        {"李四",19},
    }
    s,err:=find(students,"张三")
    if err!=nil{
        fmt.Println(err)
        return
    }
    fmt.Println(s.name,s.age)
}

字符串操作

  • strings包中有很多对字符串进行操作的方法,比如:
  • 字符串中是否包含某个子字符串:strings.Contains(str,substr)
  • 对某个子串计数strings.Count(str,substr)
  • 判断str是否以prefix开头strings.HasPrefix(str,prefix)
  • 判断str是否以suffix结尾strings.HasSuffix(str,suffix)
  • 返回substr在str中第一次出现的位置,如果没有返回-1:strings.Index(str,substr)
  • 将strs中的元素用sep拼接成一个字符串:strings.Join(strs,sep)
  • strings.LastIndex(str,substr)
  • 重复str count次:strings.Repeat(str,count)
  • 替换str中old为new,count为替换的次数:strings.Replace(str,old,new,count)
  • 将str按sep分割成字符串数组:strings.Split(str,sep)
  • strings.ToLower(str)
  • strings.ToUpper(str)
  • len(str),一个中文可能对应多个字符

字符串格式化

  • fmt包中有多个格式化方法,如:
  • 打印并换行 fmt.Println(str)
  • %v可以打印任意类型的变量fmt.Printf("%v",str)
  • 对于结构体%+v 可以打印结构体的所有字段和值,%#v打印出结构体类型名称和字段
  • 打印保留小数点后两位 fmt.Printf("%.2f",float64)

JSON处理

  • 结构体每个字段需要大写开头,否则无法被json解析
  • json包中有两个方法:
    • Marshal将结构体序列化成json字符串:json.Marshal(obj)
    • Unmarshal将json字符串反序列化成结构体:json.Unmarshal([]byte(str),obj)
type User struct {
    Name string 
    Age int `json:"age"`
}
func main() {
    user := User{"张三", 18}
    jsonStr,err := json.Marshal(user)
    if err != nil {
        panic(err)// 处理错误
    }
    fmt.Println(string(jsonStr))//需要转换为字符串
    var user2 User
    err=json.Unmarshal(jsonStr,&user2)// 需要传入指针
    if err != nil {
        panic(err)
    }
    fmt.Println(user2)// {张三 18}
}

时间处理

  • 获取当前时间time.Now()
  • 创建一个时间:time.Date(year,month,day,hour,min,sec,nsec,loc)
  • 将一个时间格式化成字符串:time.Format("2006-01-02 15:04:05")
  • 得到一个时间段:t.Sub(t2)并且获取时间段有多少分钟多少秒
  • 获取时间戳:time.Unix()
func main() {
    now := time.Now()
    fmt.Println(now)
    // 创建一个时间
    t:= time.Date(2020, 12, 12, 12, 12, 12, 12, time.Local)
    fmt.Println(t.Format("2006-01-02 15:04:05"))// 格式化
    diff:= now.Sub(t)// 时间段
    fmt.Println(diff.Minutes())
    fmt.Println(time.Unix())// 时间戳
}

数字解析

  • 在strconv包中有ParseInt、ParseFloat,Atoi等方法
func main() {
    a, _ := strconv.ParseInt("123", 10, 64)// 10进制
    b, _ := strconv.ParseFloat("123.45", 64)// 浮点数
    c, _ := strconv.Atoi("123")// 字符串转数字
    fmt.Println(a, b, c)
}

进程信息

func main() {
    //go run main.go a b c d
    fmt.Println(os.args)//["main.go", "a", "b", "c", "d"]
    fmt.Println(os.Getenv("PATH"))//获取环境变量
    fmt.Println(os.Setenv("PATH", "new path"))//设置环境变量
    //启动子进程
    buf,err:= exec.Command("grep","127.0.0.1","/etc/hosts").CombinedOutput()
    if err!=nil{
        panic(err)
    }
    fmt.Println(string(buf))//输出子进程执行结果
}