Go语言快速上手-基础语言

简介

什么是Go语言

  • 高性能、高并发Go使用标准库或基于标准库的第三方库来实现高并发
  • 语法简单、学习曲线平缓package main

    import “net/http”

    func main() {
    //将标准库的http包里,将“/”路由指向静态文件夹“.”
    http.Handle(“/”, http.FileServer(http.Dir(“.”)))
    //监听端口并启动服务
    http.ListenAndServe(“:8080”, nil)
    }
    ​标准库实现一个Http服务器
  • 丰富的标准库可以保障稳定性、兼容性
  • 完善的工具链编译、代码格式化、错误检查、帮助文档、包管理等……
  • 静态链接
  • 快速编译Go语言有着静态语言里最快的编译速度
  • 跨平台支持交叉编译
  • 垃圾回收无需考虑内存分配释放

应用领域:云计算、微服务、大数据、区块链、物联网等

Docker、Kubernetes、Istio、etcd、prometheus 几乎所有的云原生组件全是用Go实现的。

基础语法

变量

声明

  • 未使用不能声明
  • 不可以重复声明

package main
import “fmt”
func main(){

//小驼峰userName
// 大驼峰UserName

var a int
// 未使用不能声明
fmt.Println(a)
}

初始化

package main
import “fmt”
func main(){
   //变量初始化
var b int = 100
fmt.Println(b)
}

赋值

package main
import “fmt”
func main(){
   //赋值
var c float64 = 123.321
c = 321.123
fmt.Println(c)
}

可以同时给多个变量赋值package main
import “fmt”
func main(){
   var a,b,c=100,200,300;
}

自动推导

自动推导是让变量根据声明时候初始化的值去自动判断变量的类型package main
import “fmt”
func main(){
   // 自动推导
var sum = 789.654
fmt.Printf(“%T\n”,sum)//%T是打印输出类型的格式控制符
// 常用的自动推导,相当于声明+初始化
// a := 100 //会报错,因为a已经声明过了
pi := 3.1415926
fmt.Println(pi)
}

这里的变量sum被自动推导出了为float64类型

字符串

package main

import (
“fmt”
)

func main() {
var str string
str = “Hello World”
fmt.Println(str)

//字符串长度
fmt.Println(len(str))

//一个汉字3字符
ch := “中”
fmt.Println(len(ch))

//字符串拼接
str1 := “Hello”
str2 := ” World”
str3 := str1 + str2
fmt.Println(str3)

//字符串取单个字符
strr := “Hello World”
fmt.Println(str[0], strr[1])         //对应的ASCII码
fmt.Printf(“%c,%c”, strr[0], strr[1]) //输出字符
}

判断结构

if-else

package main

import “fmt”

func main() {

  //if支持一个初始化语句,只在当前判断生效
  if a := 700; a == 700 {
    fmt.Printf(“%d\n”, a)
  }

  if a := 500; a > 700 {
    fmt.Println(“a>700”)
  } else if a == 700 {
    fmt.Println(“a==700”)
  } else {
    fmt.Println(“a<700”)
  }

}

switch

Go的Switch与C的switch不一样

C的switch如果不遇到break,会跑完所有的case

而Go的switch只会跑完符合条件的case   switch a := 120; a {
  case 80:
    fmt.Println(“80”)
  case 90:
    fmt.Println(“90”)
  case 100, 110, 120:
    fmt.Println(“100,110,120”) //可以有多个值匹配
    fallthrough               //相当于continue
  default:
    fmt.Println(“default”)
  }

Go的switch支持任意的数据类型,字符串,结构体等

Go的switch判断变量可以留空,在case里添加条件,起到代替if-else的作用   //判断字符留空
  switch sc := 100; {
  case sc >= 100:
    fmt.Println(“A”)
  case sc <= 100:
    fmt.Println(“B”)
  default:
    fmt.Println(“C”)
  }

数组

package main

import “fmt”

func main() {
  //一维数组
  var a [5]int
  a[4] = 100
  fmt.Println(a[4], len(a))
  //初始化
  b := [5]int{1, 2, 3, 4, 5}
  fmt.Println(b)

  //二维数组
  var twoD [2][3]int
  for i := 0; i < 2; i++ {
    for j := 0; j < 3; j++ {
        twoD[i][j] = i + j
    }
  }
  fmt.Println(twoD)

}

切片

  • 切片是可变长度的数组,可以任意时刻去更改长度
  • Golang里Slice的结构是长度+容量+指向数组的指针,当容量不够时,会进行扩容,并返回新的Slice,因此需要赋值回去
  • Golang不支持负索引,需要借助len()进行运算

package main

import “fmt”

func main() {
  //用make创建切片
  s := make([]string, 3)
  s[0], s[1], s[2] = “a”, “b”, “c”
  fmt.Println(s[2])
  fmt.Println(len(s))

  //使用append追加元素
  //append必须将结果赋值给原数组
  s = append(s, “d”)
  s = append(s, “e”, “f”)
  fmt.Println(s, len(s))

  //make指定长度
  c := make([]string, len(s))

  //拷贝数据
  copy(c, s)
  fmt.Println(c)

  //切片取值
  fmt.Println(s[2:5]) //左闭右开
  fmt.Println(s[:5])
  fmt.Println(s[2:])

}

map

其他语言又被称为哈希、字典package main

import “fmt”

func main() {
  //make创建空map
  //key的类型为string,value的类型为int
  m := make(map[string]int)

  //读取、写入map
  m[“one”] = 1
  m[“two”] = 2
  fmt.Println(m)
  fmt.Println(len(m))
  fmt.Println(m[“one”])
  fmt.Println(m[“unknow”])

  //可以通过ok来检查指定的key是否存在
  r, ok := m[“unknow”]
  fmt.Println(r, ok)
  r, ok = m[“one”]
  fmt.Println(r, ok)

  //删除k-v对
  delete(m, “one”)

  //map的kv对是完全无序的,遍历时候不会以任何顺序输出
  m2 := map[string]int{“one”: 1, “two”: 2}
  var m3 = map[string]int{“one”: 1, “two”: 2}
  fmt.Println(m2, m3)

}

range

对于一个slice或者map可以用range进行遍历package main

import “fmt”

func main() {
  //遍历数组
  nums := []int{2, 3, 4}
  sum := 0
  //第一个参数是索引,第二个参数是索引对应的值
  for i, num := range nums {
    sum += num
    if num == 2 {
        fmt.Println(“index:”, i, “num:”, num)
    }
  }
  fmt.Println(sum)

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

  //遍历输出map的k
  for k := range m {
    fmt.Println(“k=”, k)
  }
}

函数

  • 返回值类型后置
  • 可以返回多个值
  • 通常第一个值返回真正的结果,第二个值返回错误信息

package main

import “fmt”

//返回值类型后置
func add(a, 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
}

func main() {
  fmt.Println(add(1, 2))
  v, ok := exists(map[string]string{“a”: “A”}, “a”)
  fmt.Println(v, ok)
}

指针

package main

import “fmt”

func Add(n int) {
//这里的n只是一个拷贝,不会改变原变量的值(内存地址不同)
n += 2
}

func Addptr(n *int) {
*n += 2
}

func main() {
n := 5
Add(n)
fmt.Println(n)
Addptr(&n)
fmt.Println(n)
}

结构体

  • 结构体的三种初始化赋值方式
    • 完整初始化各字段(有关键字)
    • 完整初始化各字段(无关键字)
    • 只初始化其中一部分字段(未初始化的字段默认为空值)
    • 只初始化结构体变量,后给字段赋值
  • 结构体也可以作为函数参数
    • 指针式
    • 非指针式

package main

import “fmt”

type user struct {
name     string
password string
}

func main() {
//第一种
a := user{name: “XiaoZhi”, password: “123456”}
//第二种
b := user{“XiaoZhi”, “123456”}
//第三种
//可以只初始化一个字段,但必须指明初始化哪个字段,没有初始化的字段默认为空
c := user{name: “XiaoZhi”}
fmt.Println(c.password)
c.password = “123456”
fmt.Println(c.password)
//第四种
var d user
d.name = “XiaoZhi”
d.password = “123456”
fmt.Println(a, b, c, d)

}

//结构体作为函数参数
func CheckPassword(u user, password string) bool {
return u.password == password
}

//指针式
func CheckPassword2(u *user, password string) bool {
return u.password == password
}

使用指针可以实现对结构体变量的修改,同时避免大结构变量产生拷贝的开销

结构体函数

类似于类成员函数,package main

import “fmt”

type user struct {
  name     string
  password string
}

func (u user) CheckPassword(password string) bool {
  return u.password == password
}
func (u *user) ResetPassword(password string) {
  u.password = password
}

func main() {
  u := user{“XiaoZhi”, “admin”}
  fmt.Println(u.CheckPassword(“admin”))
  u.ResetPassword(“adminadmin”)
  fmt.Println(u.password)
}

错误处理

在Golang里,符合语言错误处理的习惯是,使用一个单独的返回值来传递错误信息

区别于Java中的异常处理,Go中可以清晰地知道哪个函数返回了错误,并可以用简单的if-else去处理错误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() {
  v, err := findUser([]User{{“Yang”, “1024”}}, “Yang”)
  if err != nil {
    fmt.Println(err)
    return
  }
  //查找成功,继续执行,打印用户姓名
  fmt.Println(v.name)

  //查找失败,输出错误信息
  if u, err := findUser([]User{{“wang”, “1234”}}, “li”); err != nil {
    fmt.Println(err)
    return
  } else {
    fmt.Println(u.name)
  }
}

字符串操作

package main

import (
“fmt”
“strings”
)

func main() {
a := “Hello”
fmt.Println(strings.Contains(a, “ll”)) //查询字串是否存在
fmt.Println(strings.Count(a, “l”)) //字串出现次数计数
fmt.Println(strings.HasPrefix(a, “he”)) //前缀判断
fmt.Println(strings.HasSuffix(a, “llo”)) //后缀判断
fmt.Println(strings.Index(a, “ll”)) //字串位置
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-b-c”, “-“)) //分割字符串为数组
fmt.Println(strings.ToUpper(“abc”)) //转大写
fmt.Println(strings.ToLower(“abc”)) //转小写
fmt.Println(len(a)) //获取字符串长度
fmt.Println(len(“你好”)) //一个中文3个字符长度

}

字符串格式化

package main

import “fmt”

type Point struct {
x, y int
}

func main() {
s := “hello”
n := “123”
p := Point{1, 2}
fmt.Println(s, n)
fmt.Println(p)

//%v自动识别类型
fmt.Printf(“s=%v\n”, s)
fmt.Println(“n=%v\n”, n)
fmt.Println(“p=%v\n”, p)

//%+v得到更完整的结构
fmt.Printf(“p=%+v\n”, p)

//%#v更更进一步细化
fmt.Printf(“p=%#v\n”, p) //结构体的类型名称、字段名字及值

//设置小数点、精确度
b := 3.1415926535
fmt.Println(b)
fmt.Printf(“%.2f\n”, b)

}

JSON处理

  • JSON首字母必须大写
  • 序列出来的字符串是一个大写字母开头的,如果输出需要小写,则需要在结构体中添加tag,在输出时会小写
  • 需要使用强制类型转换为字符串,否则为一个16进制字符串

package main

import (
“encoding/json”
“fmt”
)

type userInfo struct {
//JSON首字母必须大写
Name string
Age int `json:”age”` //添加tag
Hobby []string
}

func main() {
a := userInfo{“XiaoZhi”, 24, []string{“sing”, “dance”, “rap”, “play basketball”}}

//序列化
//序列出来的字符串是一个大写字母开头的
//如果输出需要小写,则需要在结构体中添加tag,在输出时会小写
buf, err := json.Marshal(a)
if err != nil {
//运行时恐慌
//在panic被抛出之后,如果没有在程序里添加任何保护措施的话,程序就会在打印出panic的详情,终止运行
panic(err)
}

// 序列化为字符串
fmt.Println(buf) //十六进制字符串
// 强制类型转换
fmt.Println(string(buf))

//应用缩进来格式化输出
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)
}

时间处理

package main

import (
“fmt”
“time”
)

func main() {
//快速获取当前时间
now := time.Now()
fmt.Println(now)

//构造一个带时区的时间
t := time.Date(2023, 1, 15, 12, 0, 36, 6, time.UTC)
t2 := time.Date(2023, 1, 15, 12, 20, 36, 6, time.UTC)
fmt.Println(t)
//获取时间点信息
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute())

//格式化一个时间字符串
fmt.Println(t.Format(“2006-01-02 15:04:05”))

//时间相减,获得时间段
diff := t2.Sub(t)
fmt.Println(diff)
//输出时间段内有多少分钟,多少秒
fmt.Println(diff.Minutes(), diff.Seconds())

//第一个参数是时间字符串格式,第二个为具体时间字符串
t3, err := time.Parse(“2006-01-02 15:04:05”, “2022-03-27 01:25:36”)
if err != nil {
panic(err)
}
fmt.Println(t3 == t)
//获取时间戳
fmt.Println(now.Unix())
}

数字解析

常用数字解析函数package main

import (
“fmt”
“strconv” //string convert缩写
)

func main() {
f, _ := strconv.ParseFloat(“1.234”, 64)
fmt.Println(f)

//第二个参数表示进制(8、10、16,如果传0为自动推测)
//第三个参数为精度
n, _ := strconv.ParseInt(“111”, 10, 64)
fmt.Println(n)
n, _ = strconv.ParseInt(“0x1000”, 0, 64)
fmt.Println(n)

//字符串快速转数字
n2, _ := strconv.Atoi(“123”)
fmt.Println(n2)
//数字转字符串
n3 := strconv.Itoa(132)
fmt.Println(n3)

}

进程信息

package main

import (
“fmt”
“os”
“os/exec”
)

func main() {
//当执行当前程序 包含参数时,读取参数
fmt.Println(os.Args)
//打印环境变量
fmt.Println(os.Getenv(“PATH”))
// 设置环境变量
fmt.Println(os.Setenv(“AA”, “BB”))
// 启动子进程,获取输入输出
buf, err := exec.Command(“java”, “–version”).CombinedOutput()
if err != nil {
panic(err)
}
fmt.Println(string(buf))
}

##

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇