邂逅goLang,基础语法|青训营笔记

106 阅读5分钟

在本次字节青训中,因为内容多为干货,第一次接触goLang的我对于课程中基本语法的一笔带过还有很多不熟练的地方,简单记录一下自己熟悉goLang基础语法的过程

基本数据类型与写法

go是一个强类型编程语言,基础的数据类型包括数字类型(整型、浮点型)、布尔型、字符和字符串类型,给我留下比较深刻的印象的是go的写法,相比较同为服务端编程语言的java,我感觉go在语言本身更相似于Python和TypeScript,只是语言本身的话,所表现出来的感觉的是灵巧、轻便。

//输出
fmt.Println("hello world")
//整数
var a = 3 // 在声明时直接赋值,会进行类型猜测
//浮点数
var b = 3.14
var x float32 // 声明而未直接赋值时需要注明类型
var y float64
x = 3.213
y = 2.1231

//字符串
var c = "hello c"

//常量
const h = 500000000
const i = 3e20 / h
const st string = "go study time"

fmt.Println(a, b, c, x, y, math.Sin(i), st)

// 简写,声明并且赋值
aa := 123
bb := "hello bb"
cc := 3.34123

dd := "welcome" + bb
fmt.Println(aa, bb, cc, dd)

流程控制

在可以简单声明变量过后,那么便可以进行流程控制语句的学习,无论是if语句还是switch语句,在我看来都是功能更强大、更灵活的写法,尤其是switch,如果是我在平时进行编程的时候,switch可以说是很少使用的一种语句,因为尽管多个if else语句看起来有多么“low”,仍要比switch语句来的方便和灵活,也就是在进行错误类型处理的时候使用switch是最佳方案,但是在go中的switch语句,非常的灵活,甚至可以完全取代多重if的写法。

注意在使用for和if等流程控制语句时,大括号必须写在控制语句之后,不能另起一行。

//循环
for i := 7; i < 9; i++ {
   fmt.Println(i)
}

for i := 0; i < 5; i++ {
   if i%2 == 0 {
      continue
   }
   fmt.Println(i)
}
//if语句
if 7%2 == 1 {
   fmt.Println("right")
} else {
   fmt.Println("false")
}

if num := 9; num < 7 {
   fmt.Println("num < 7")
} else if num < 10 {
   fmt.Println("num < 10")
} else {
   fmt.Println("num >= 10")
}

//switch语句
switchNum := 2
// 可以直接把变量作为switch传入的参数,然后在内部根据参数灵活处理
switch switchNum {
//不用编写break,go的switch内部就是单个任务执行,即使不注明break,也会在目标处退出switch
case 1:
   fmt.Println("one")
case 2:
   fmt.Println("two")
case 3:
   fmt.Println("three")
default:
   fmt.Println("default")
}

对于json的处理

当我们在与前端交互的时候,难免会进行前后端通讯,不论是采用前后端分离还是前后端一体,前端在发送信息给后端接口的时候,可以有很多种方式,更多的是采用json作为数据传输的格式,而go对json的原生处理主要依赖于encoding/json依赖包,下面给出处理的简单语法。

package main

import (
   "encoding/json"
   "fmt"
)

type userInfo struct {
   Name  string
   Age   int `json:"age"` // 起别名
   Hobby []string
}

func main() {
   a := userInfo{
      Name:  "mx",
      Age:   18,
      Hobby: []string{"GoLang", "TypeScript"},
   }
   // 自动转为json格式
   buf, err := json.Marshal(a)
   if err != nil {
      panic(err)
   }
   fmt.Println(buf)
   fmt.Println(string(buf))

   // 转为json格式并自动换行
   buf, err = json.MarshalIndent(a, "", "\t")
   if err != nil {
      panic(err)
   }
   fmt.Println(string(buf))

   var b userInfo
   err = json.Unmarshal(buf, &b)
   if err != nil {
      panic(err)
   }
   fmt.Printf("%#v\n", b)
}

常用依赖库的灵活使用

fmt依赖库:

对于fmt依赖库,可以采用Printf对于打印的格式灵活进行格式化,如下:

package main

import "fmt"

type point struct {
   x, y int
}

func main() {
   a := "hello"
   n := 123
   p := point{x: 1, y: 2}

   fmt.Println(a, n)
   fmt.Println(p)

   fmt.Printf("a=%v\n", a)
   fmt.Printf("p=%v\n", p)  // 打印value
   fmt.Printf("p=%+v\n", p) // 打印key value的形式
   fmt.Printf("a=%#v\n", a) // "hello" 注明类型
   fmt.Printf("p=%#v\n", p) // main.point{x:1, y:2} 注明类型

   f := 3.141592
   fmt.Printf("%.2f\n", f) // 格式化保留小数点位数
}

errors依赖库:

错误处理可以很好的反应一个系统的健壮性,而golang本身集成了很好的错误处理,在你进行流程、I/O或者调用函数的时候都会默认返回当出现错误时的错误信息,让我们可以进行更方便也更完善的系统错误处理。

package main

import (
   "errors"
   "fmt"
)

type user struct {
   name     string
   password string
}

//查询用户,如果查到将用户返回回去,如果没查到,返回错误
func findUser(users []user, name string) (v *user, err error) {
   for _, u := range users {
      if u.name == name {
         return &u, nil
      }
   }
   return nil, errors.New("not found")
}

func main() {

   u, err := findUser([]user{{name: "张三", password: "123"}}, "张三")
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(u)

   if u, err := findUser([]user{{"wang", "123"}}, "li"); err != nil {
      fmt.Println(err)
      return
   } else {
      fmt.Println(u)
   }
}

strings依赖库

strings依赖库主要是针对于字符串操作,可以提高我们编程效率的同时给我们提供代码可读性更高也更简便、高效率的编码方式。可以对字符串处理提供更多的处理方式。

package main

import (
   "fmt"
   "strings"
)

func main() {
   a := "hello world"
   fmt.Println(strings.Contains(a, "ll")) // 检测是否包含
   fmt.Println(strings.Count(a, "l")) // 计数
   fmt.Println(strings.Compare(a, "HELLO WORLD")) // 字符串比较
   fmt.Println(strings.HasPrefix(a, "hel")) // 检测是否以目标字符串作为开头
   fmt.Println(strings.HasSuffix(a, "rld")) // 检测是否以目标字符串作为结尾
   fmt.Println(strings.Index(a, "l")) // 查找目标字符串的下标
   fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // 数组合并为字符串
   fmt.Println(strings.Repeat(a, 2)) // 目标字符重复
   fmt.Println(strings.Replace(a, "e", "E", -1)) // 目标字符替换
   fmt.Println(strings.Split("a-v-b-v", "-")) // 字符串分割
   fmt.Println(strings.ToLower("ABSAD")) // 转小写
   fmt.Println(strings.ToUpper("asdas")) // 转大写
   fmt.Println(len("你好")) // 输出长度
}

time依赖库

time库类似于math等第三方库,是go提供的主要针对于我们对于时间的处理,使用这个库,可以对时间一类的处理提供更方便的解决方案,下面给出使用time库的基础语法。

package main

import (
   "fmt"
   "time"
)

func main() {
   now := time.Now()
   fmt.Println(now) // 打印当前时间
   t := time.Date(2022, 1, 1, 1, 30, 30, 0, time.UTC) // 自定义时间
   t2 := time.Date(2022, 1, 2, 1, 30, 30, 0, time.UTC)
   fmt.Println(t) 
   // 分块输出时间,灵活提取出任何想要的时间单位
   fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
   fmt.Println(t.Format("2006-01-01 15:01:05"))

   diff := t2.Sub(t) // 时间作差
   fmt.Println(diff)
   fmt.Println(diff.Hours(), diff.Minutes(), diff.Seconds())

   // 格式化时间输出格式
   t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
   if err != nil {
      fmt.Println(err)
   }
   fmt.Println(t3)
   fmt.Println(now.Unix())
}

对于GoLang的学习还在继续