Go 语言入门 | 青训营

97 阅读3分钟

Go语言基础

Go语言背景 & 字节选择Go背景

Go语言特性-类似Java, C,C++,但会更易上手更灵活

  1. 高性能、高并发
  2. 语法简单、学习曲线平缓
  3. 标准库丰富
  4. 工具链完善
  5. 静态链接
  6. 快速编译
  7. 跨平台
  8. 垃圾回收

仅用几行代码即可实现http服务器运行,服务器支持静态文件访问,支持高并发高性能

package main

import (
    "net/http"
)

func main(){
    http.Handle("/", http.FileServer(http.Dir(".")))
    http.ListenAndServe(":8080", nil)
}

使用Go语言的公司:

ByteDance,Tencet,Meituan,DiDi,Baidu,Google,Meta,bilibili,PingCAP等

字节prefere go reason:

  1. 性能问题原因,Python->Go

  2. C++太过底层不适合在线Web业务

  3. 早期团队非Java背景

  4. 性能好

  5. deploy简单、学习成本低

  6. 公司内部偏向,内部RPC和HTTP框架的推广

基础语法

Hello World

package main

import (

“fmt” //标准化format包,导入字符串

)


func main(){

fmt.Println(“hello world”)

}

变量

package main

import (
“fmt” //format包
“math”//math数学包
)


func main(){

var a = “initial” //自动推到变量类型

var b/c int = 1,2

var d = true

var e float64

f := float32(e)

g := a + “foo” //(字符串是内置类型,可直接+-,也可直接用=去比较)

fmt.Println( alb,c,d,e,f) // initial 1 2 true 0 0

fmt.Println(g) //initialfoo

const s string = “constant”

const h = 500000000

const I = 3e20/h

fmt.Println(s,h,i,math.Sin(h), math.Sin(i))

}
两种variable declare方式:
  1. var a = sth, Go自动推断vairable type

    var a int = 2, 强制declare variable type

  2. f := sth

当无具体确定类型,Go会根据上下文自动确定类型


常量keyword: const

if-else

if后面不加括号,如果加了括号,编译器在编译过程中会自动去掉

example code:

if num:=9; num<0{

//do one;

} else if num<10{

//do two

} else{
// do default

}

Loop-“for”:

若没有condition,便是死循环

for{} //死循环

有condition则是标准for循环,下属example initialize j=7,循环两次

for j:=7;j<9;j++{…}//正常for loop 此外,与C,C++,Java相同,可用return,continue,break等干扰或打断当前循环

switch case

switch case中,每个case底下不需要break来结束当前case

switch a {

case 1:

    ...

case 2, 3: //case可并存

    ...

default:

    ...

}

condition可以不加在switch后,而是加在case后,可以让嵌套if...else...更清晰

t := time.Now()
switch{
   case t.Hour() < 12:
       //do sth
   default:
       //do default things
}
//等同于if t.Hour()<12{} else {//default}

数组

固定长度数据类型来读取、存储data

var a [5]int //initiliaze一个可以存放五个数字的数组a

a[4] = 100 //写入第四个位置的值

b := [5]int{1,2,3,4,5}

真实使用情况下很少使用数组,因为其长度固定,更多情况下是使用切片

切片

可变长度数组,可以任意时刻去更改长度

s:=make([]string, 3) //用make去创造一个切片

s = append(s, “d”)

s[2:5] //同python,取出第二个到第五个位置(不包括第五个)的元素

map

map中完全无序

m:=make(map[string]int) //map[keyType]valueType
//存到map中
m[“one”]=1
m[“two”]=2

// 删除KV对
delete(m, "one") //delete(map, <keyName>)

// 查找是否有这个key存在
r, ok:= m["unknow"]
// ok表示map中是否有key存在, false表示map中没有当前key
fmt.Println(r,ok) // 0 false

range

对于slice或者map可以用range来快速遍历,让代码更加简洁

range会返回index,value两个值,若不需要index,直接用‘_’省略

nums := []int{2,3,4}
sum := 0

for i, num := range nums{
    ...
}

函数

func namevarName varType,…) returnType{

    return smth

}

指针

当在函数中需要对内存中value直接进行更改时,可以调用pointer

func add2(n int){n+=2} //无效写法,只会改function内copy的值

func add2(n *int){*n += 2} //correct version

add2ptr (&n) //调用要用address

结构体

constructor可用于自己定义一个结构


//class中define两个attribute

type name struct{

    name string

    password string

} 

// (u user) 表示属于这一类中的方法

func (u user) checkPassword(password string) bool{

}

错误处理

填写function时可以return一个error type的东西,如果出错,给一个error,外加自定义相应的message

func findUser(users []user, name string) (v *user, err error){
    if u.name == name{
        return &u, nil
    }
    return nil, errors.New("not found")
}

数字解析

使用‘strconv’包进行解析一个字符串

syntax: func ParseInt(s string, base int, bitSize int) (i int64, err error) 若base为0名则该字符串的前缀隐含base, 比如字符串开头为“0b",“0o", "0x"

strcov.ParseFloat("1.234", 64) //return float64的数字
strcov.ParseInt("111", 10, 64) //输入字符串进制 10进制 int64的数字