go语言基础 | 青训营

87 阅读7分钟

go语言对于我来说是一个全新的语言,在学习这个语言开始需要自己有时间去慢慢琢磨,但是有些与我们所学的知识相关或者类似,也不用太担心。

GO(golang)基础

一. GO语言

  • 高性能,高并发:有和C++和JAVA媲美的性能,对高变化的支持,只需要使用标准库或任意基于标准库的第三方库就可以开发高并发程序
  • 语法简单,学习曲线平缓:类似C语言,在C语言基础上进行大幅度简化,上手容易
  • 丰富的标准库:降低学习成本,标准库有很高的稳定性和兼容性
  • 完善的工具链:编译,代码格式化,错误检测,帮助文档,管理和代码补充提示,完整的单元格式框架,能够支持单元测试,性能测试,代码覆盖率,检测,性能优化
  • 静态链接:go语言里默认是静态链接的
  • 快速编译:编译速度很快
  • 跨平台:能在Linux,window等操作系统运行,也能够开发安卓,ios软件
  • 垃圾回收:无需考虑业务分配

二:基础语法

2.1.hello world

````package main //main包一部分,入口包
   import(
         "fmt"    //fmt包输入输出字符,格式化字符串
   )
    func main(){
     fmt.Println("hello world")   //调用,输出hello world
    }`
    运行:go run hello world.go

2.2.GO的变量

  • 类型字符串,整数,浮点型,布尔型
  • go语言可以直接用加号去拼接
g:=a+"foo"
  • 变量的声明两种
var b,c int =1,2
f:=float32(e)

**2.3.常量声明:

在go里常量没确定的类型,根据使用是上下文自动确定类型**

const s string ="constant"
const h =500000
const i =3e20/h

2.4.if else用法和C/C++类似,

  • 不同的是
  1. go里if后无括号
  2. if后面直接跟大括号
if 7%2==0{
     fmt.Println("7 is even")
}else{
     fmt.Println("7 is odd")
}

2.5.循环:for循环

也是没有()

for{  
  fmt.Println("loop")  
  break  
}
for j:=7;j<9;j++ {  
   fmt.Println(j)  
}
for n:=0;n<5;n++{  
  if n%2==0{  
   continue  
}  
fmt.Println(n)  
}

2.6.switch

switch后不需要括号,在go里写默认有break,可以用任意变量的结构体 与c不同,没有break,c语言是一直执行完,go执行一个合适的就跳出

switch a{
case 1:              //若执行case 1,执行完直接跳出switch,到t那里
   fmt.Println("one")
case 2:
   fmt.Println("two")
case 3:
   fmt.Println("three")
case 4,5:
   fmt.println("four or five")
default:
   fmt.Println("other")
}

t:=time.Now()
switch{            //可以取代任意的if else语句,switch后面不加任意变量
case t.Hour()<12:             //在case里面写条件分支
   fmt.Println("It's before noon")
default:
   fmt.Println("It's after noon")
}

2.7.数组

数组可以很方便读取,存取特定的值

var a[5]int  //可以存放5个int元素的数组a,
a[4]=100    //写入第4个位置的值
fmt.Println(a[4],len(a))  //读取第4个位置的值

2.8.切片

是一个可变长度的数组,可任意时刻去更改长度,用make串联切片,append追加元素,append的结果必须赋值回元素组

s:=make([]string,3)
s[0]="a"
s[1]="b"
s[2]="c"
fmt.Println("get:",s[2])  //c
fmt.Println("len:",len(s)) //3

s=append(s,"d")
s=append(s,"e","f")
fmt.Println(s)  //[a b c d e f]

c:=make([]string,len(s))
copy(c,s)
fmt.Println(c)  //[a b c d e f]

fmt.Println(s[2:5])  //2号到5号的元素,不包括5号元素 [c d e]
fmt.Println(s[:5])   //从开始一直取到5号元素,不包括5号 [a b c d e]
fmt.Println(s[2:])   //从2号元素开始一直取完 [c d e f]

2.9map

用make串联

m:=make(map[string]int)     //第一个k类型,第二个是value类型
m["one"]=1
m["two"]=2
fmt.Println(m)                  //map[one:1 two:2]
fmt.Println(len(m))             //2
fmt.Println(m["one"])          //1
fmt.Println(m["unknow"])      //0

r,ok:=m["unknow"]     //读取,加ok判断到底有没有其存在
fmt.Println(r,ok)   //0 false

delete(m,"one") //删除k对

2.10.range

快速遍历,第一个是索引,第二是对应位置的值

m:=map[string]string{"a":"A","b":"B"}
for k,v:=range m{
   fmt.Println(k,v) //b B; a A
}

2.11.加法

func add(a int,b int)int{
return a+b
}
//第一个是真是值,第二个是错误返回信息
func exists(m map[string]string,k string)(v string,ok bool){ 
   v,ok=m[k]
  return v,ok 
}

2.12指针

func add2ptr(n *int){   
     *n+=2          //主要*号
 }
 func main(){
 add2ptr(&n)       //加&才能编译通过
}

2.13结构体

带类型的字段的集合

type user struct{       //定义user结构体,包含两个字段 name,password
   name  string
   password string
}
func main(){
   a:=user(name:"wang",password:"1024") //结构体名称初始化一个结构体变量
   b:=user("wang","1024")
   c:=user{name:"wang")
   c.password="1024"  //没初始化的会变成空值就是0
   d.name="wang"
   d.password="1024"  //可以用.加字段名 向结构体读和写数据
   fmt.Println(a,b,c,d)   //{wang 1024} {wang 1024} {wang 1024} {wang 1024}
   fmt.Println(checkpassword(a,"haha") //false
   fmt.Println(checkpassword(&a,"haha") //false
}
//指针的结构体
func checkpassword(u *user,password string) bool{
     return u.password==password
  }

2.14错误处理

加error 代表可能返回错误

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{{"wang","1024"}},"wang")
   if err!=nil{        //判断err是否存在
     fmt.Println(err)
      return
   } 
   fmt.println(u.name)  //wang
   if u,err:=findUser([]user{{"wang","1024"}},"li");err!=nil{
      fmt.Println(err)   //not found
      return
    }else{
        fmt.Println(u.name)
    }
  }

2.15 字符串操作

  • contains 判断一个字符串是否包含于另一个字符串
  • count 字符串计数
  • index 查找某个字符串的位置
  • join 连接多个字符串
  • repeat 重复多个字符串
  • len 获取字符串长度
func main() {   
   a :="hello"    
  fmt.Println(strings.Contains(a, "ll"))     // true    
  fmt. Println(strings.Count(a, "l" ))         // 2    
  fmt. Println( strings .HasPrefix(a, "he" ))   // true   
  fmt.Println(strings.HasSuffix(a, "llo"))    // true    
  fmt . Println( strings.Index(a, "ll"))    // 2    
  fmt. Println(strings.Join([]stringl"he""llo"), "-")) // he-llo
  fmt .Println(strings . Repeat(a, 2))  // hellohello   
  fmt.Println(strings.Replace(a, "e""E", -1))   // hEllo   
  fmt.Println(strings.Split("a-b-c""-"))   //[abc]  
  fmt. Println( strings. ToLower(a))   // hello   
  fmt. Println( strings. ToUpper(a))   // HELLO  
  fmt.Println(len(a))  // 5  
   b :="你好"   
  fmt.Println(len(b)) // 6  
}

字符串格式化

  • %v 打印任意变量
  • %d 打印数字
  • %s 打印字符串
  • %+v 打印更加详细的结构
  • %#v 进一步详细
  • %.2f 保留两位小数
type point struct {
   x, y int  
}
func main( ) {  
  s :="hello"    
  n :=123    
  p := point{12}    
  fmt.Println(s, n) // hello 123
  fmt.Println(p) // {1 2}   
  
  fmt.Printf("s=%v\n", s)  // s=hello    
  fmt.Printf"n=%v\n", n)  // n=123   
  fmt.Printf("p=%v\n", p)   // p={1 2}    
  fmt.Printf("p=%+v\n", p)  // p={x:1 y:2}   
  fmt.Printf("p=%#v\n", p)   // p=main. pointl{x:1, y:2}  //整个类型名称,字段名字和值
  
  f:=3.141592653
  fmt.Println(f)   //3.141592653
  fmt.Printf("%.2f\n",f)  //3.14
}

2.16.json处理

结构体中让每一个字段的第一个字母是大写

type userInfo struct{
    Name string
    Age int 'json:"age"'
    hobby []string
}

func main(){
  a:userInfo{Name:"wang",Age:18,Hobby: []string{"Golang",TyprScript}}
  buf,err:=json.Marshal(a)   
  if err!=nil{
      panic(err)
  }
fmt.Println(buf)  //{123 34 76 97...}   //会变成一个数组
fmt.Println(string(buf))  //{"Name":"wang" "age":"18" "Hobby"["Golang",TyprScript]}  string强制类型转换成字符串

2.17 时间处理

常用:time.Now,time.Date,.sub对时间段做减法

func main(){
now:=time.Now()  //获取当前时间
fmt.Println(now)
t:=time.Date(2022,3,27,1,25,36,0,time.UTC)  //构造时间
fmt.Println(t)          //2022-03-27  01:25:36  +0000  UTC
fmt.Println(t.Year(),t.Month(),t.Day(),t.Hour(),t.Minute())//2022 March 27 1 25
t2:=time.Date(2022,3,27,2,30,36,0,time.UTC)
diff:t2.Sub(t)  //用.sub对两个时间段做一个减法,得到一个时间段
fmt.Println(diff)  //1小时5分钟0秒
fmt.Println(diff.Minutes()),diff.Seconds()) //65 3900
fmt.Println(t.Format("2006-01-02 15:04:05")) //格式化一个时间 2022-03-27 01:25:36 
t3,err:=time.Parse("2006-01-02 15:04:05","2022-03-27 01:25:36 ")
fmt.Println(time.Unix())  //获取时间挫

2.18 数字解析

strconv ParseFloat,ParseInt解析字符串

f,_:=strconv.ParseFloat("1.234",64)
fmt.Println(f)  //1.234
//第一个是字符串,第二个是进制,传0就是自动推测,第三个代表返回是64位精度的整数
n,_:=strconv.ParseInt("111",10,64) 
fmt.Println(n) //111
n,_:=strconv.Atoi("123")   //快速把一个时间字符串转化为数字
fmt.Println(n2)  //123

2.19 进程信息

os.Args

func main() {  
  // go run example/20-env/main.go a b C d  
  fmt.Println(os.Args)  
  //[/var/folders/8p/n34xxfnx38dg8bv_ x8l62t_ m0000gn/T/go-  build3406981276/b001/exe/main a b C d]  
//长度为5,第一个代表自身的路径+名字
  
fmt.Println(os .Getenv("PATH"))    // /usr/local/go/bin...    
fmt.Println(os. Setenv"AA""BB" ))