Go语言基础
Go语言背景 & 字节选择Go背景
Go语言特性-类似Java, C,C++,但会更易上手更灵活
- 高性能、高并发
- 语法简单、学习曲线平缓
- 标准库丰富
- 工具链完善
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
仅用几行代码即可实现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:
-
性能问题原因,Python->Go
-
C++太过底层不适合在线Web业务
-
早期团队非Java背景
-
性能好
-
deploy简单、学习成本低
-
公司内部偏向,内部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方式:
-
var a = sth, Go自动推断vairable type或
var a int = 2, 强制declare variable type -
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 name(varName 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的数字