简介
Go语言优点
- 高性能、高并发
- 语法简单、学习曲线平缓
- 丰富标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
实现一个静态文件访问,支持高并发、高性能的服务器:
package main
include (
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir(".")))
http.ListenAndServe(":8080", nil)
}
为什么使用Go
- 最初使用的 Python,由于性能问题换成了 Go
- c++ 不太适合在线 Web 业务
- 早期团队非 Java 背景
- 性能比较好
- 部署简单、学习成本低
- 内部 RPC 和 HTTP 框架的推广
基础语法
Hello World
package main
include (
"fmt"
)
func main() {
fmt.Println("hello world")
}
编译、运行:
go run ./main.go
------------------------
go build ./main.go
./main
变量声明:
var a = "initial"
var b, c int = 1, 2
var d = true
var e float64
f := float32(e)
g := a + "foo"
const s string = "constant"
const h = 5000000
const i = 3e20 / h
if-else:
if num := 7; num % 2 == 0 {
.....
} else if num < 10 {
.....
} else {
.....
}
for循环:
for {
// 死循环
}
for j := 1; j < 9; j++ {
if j % 2 == 0 {
continue
}
break
}
i := 1
for i < 100 {
i = i + 1
}
switch语句(自带break):
package matn
import (
"fmt"
"time"
)
func main() (
a := 2
switch a (
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
default:
fmt.Println("other")
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
}
数组(固定长度):
var a [5]int
fmt.Println(len(a))
b := [5]int{1, 2, 3, 4, 5}
var twoD [2][3]int
切片(可变长度):
s := make([]string, 3)
s[0] = "a"
s = append(s, "d")
c := make([]string, len(s))
copy(c, s)
fmt.Println(s[:2], s[3:], s[1:3])
map(无序):
m := make(map[string]int)
m["one"] = 1
r, ok := m["unknow"] // 0, false
delete(m, "one")
m2 := make(map[string]int){"one": 1, "two": 2}
range遍历:
arr := [3]int{}
arr[0] = 1
arr[1] = 2
arr[2] = 3
// index是数组下标,value对应的值
for index, value := range arr {
fmt.Println(index, value)
}
m := map[string]int{"one": 1, "two": 2}
//key是map的key,value是map的value
for key, value := range (m) {
fmt.Println(key, value)
}
函数:
// 函数名add,参数a, b均为int,返回值为int
func add(a, b int) int {
return a + b
}
// 支持多值返回
func exists(m map[string]int, key string) (v int, ok bool) {
v, ok := m[key]
return // 上面已经给出返回v,ok,所以直接return就可以
}
指针
func add2(n *int) {
*n += 2
}
n := 5
add2(&n)
结构体:
package main
import "fmt"
func main() {
// 直接初始化时指定
user := User{name: "chengyunlai", password: "root"}
fmt.Println(user)
// 修改名称
user.name = "Cheng"
fmt.Println(user)
// 定义一个变量再指定属性
user2 := User{}
user2.name = "GoLang"
fmt.Println(checkPassword(&user, "123"))
fmt.Println(user.checkPassword("123"))
}
type User struct {
name string
password string
}
// 指针可以减少拷贝开销,也可以修改原值
// 指针也是用.访问成员
func checkPassword(u *User, pass string) bool {
return u.password == pass
}
// 结构体方法(成员函数)
func (u *User) resetPassword(password string) {
u.password = password
}
func (u *User) resetUserName(userName string) {
u.name = userName
}
// 不带指针的结构体方法
func (u User) checkPassword(pass string) bool {
return u.password == pass
}
错误处理
package main
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 // nil为空值
}
}
return nil, errors.New("not found")
}
func main() {
if u, err := findUser([]user{{"wang","1024"}}, "wang"); err != nil {
fmt.PrintIn(err) // not found
return
} else {
fmt.Printin(u.name)
}
}
字符串操作
package main
import (
"fmt"
"strings"
)
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, "lo")) // true
fmt.Println(strings.Index(a, "ll")) // 2
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
fmt.Println(strings.Repeat(a, 2)) // hellohello
// If n < 0, there is no limit on the number of replacements.
fmt.Println(strings.Replace(a, "l", "L", 1)) // heLlo
fmt.Println(strings.Replace(a, "l", "L", -1)) // heLLo
fmt.Println(strings.Split("a,b,c", ",")) // [a b c]
fmt.Println(strings.ToLower(a)) // hello
fmt.Println(strings.ToUpper(a)) // HELLO
fmt.Println(len(a)) // 5
b := "你好"
fmt.Println(len(a)) // 5
}
字符串结构化
package main
import "fmt"
type point struct {
x, y int
}
func main() {
s := "hello"
n := 123
p := point(1, 2)
fmt.Println(s, n) // hello 123
fmt.PrintIn(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.point{x:1,y:2}
f := 3.141592653
fmt.PrintIn(f) // 3.141592653
fmt.Printf("%.2f\n", f) // 3.14
}
JSON处理
package main
import (
"encoding/json"
"fmt"
)
// 要求结构体的变量首字母为大写
type User struct {
Name string `json:"name"` // 当转json时指定key的名称
Age int `json:"age"`
}
func main() {
user := User{Name: "Chengyunlai", Age: 24}
fmt.Println(user) //{Chengyunlai 24}
// 转json
res, err := json.Marshal(user)
fmt.Println(res) // [123 34 78 97 ...] (乱七八糟数字)
fmt.Println(string(res)) //{"Name":"Chengyunlai", "Age":24}
fmt.Println(err)
// 反序列化
user2 := User{}
json.Unmarshal(res, &user2)
fmt.Println(user2) //{Chengyunlai 24}
}
时间处理
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println(now) // 2023-05-12 17:32:12.0876215 +0800 CST m=+0.005319101
// 构造时间
t1 := time.Date(2023, 05, 12, 17, 32, 0, 0, time.UTC)
t2 := time.Date(2023, 05, 12, 18, 32, 0, 0, time.UTC)
fmt.Println(t1) // 2023-05-12 17:32:00 +0000 UTC
// 方法
fmt.Println(t1.Year(), t1.Month(), t1.Day(), t1.Hour(), t1.Minute())
fmt.Println(t1.Format("2006-01-02 15:04:05")) // 2023-05-12 17:32:00
diff := t2.Sub(t1)
fmt.Println(diff) // 1h 0m 0s
fmt.Println(diff.Minutes(), diff.Seconds()) // 60 3600
t3, err := time.Parse("2006-01-02 15:04:05", "2023-05-12 17:39:00") // 字符串解析
if err != nil {
fmt.Println(err)
}
fmt.Println(t3)
// 获取时间戳
fmt.Println(now.Unix()) // 168388446
}
数字解析
package main
import (
"fmt"
"strconv"
)
func main() {
f, _ := strconv.ParseFloat("1.01545", 64) // 64位
f, _ := strconv.ParseInt("111", 2, 64) // 字符串表示是二进制
fmt.Println(f) // 7
f, _ := strconv.ParseInt("0x1000", 0, 64) // 自动推测进制
fmt.Println(f) // 4096
n, _ := strconv.Atoi("123")
fmt.Println(n) // 转数字
n, err := strconv.Atoi("AAA")
fmt.Println(n, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}
进程信息
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
// go run 这个程序 a b c d
fmt.Println(os.Args) // 获取命令行参数 [C:\Users\12579\AppData\Local\Temp\go-build3318116271\b001\exe\main.exe a b c d]
fmt.Println(os.Getenv("PATH")) // 获取环境变量
fmt.Println(os.Setenv("AA","BB")) // 写入环境变量
println("----")
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput() // 命令行执行
if err != nil {
panic(err) // 抛出异常
}
fmt.Println(string(buf))
}