GO语言基础语法
1什么是GO语言
特点:
- 高性能、高并发
- 语法简单、学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
开发又多简单:通过实现一个简单的http服务器来了解一下
package main
import "net/http"
func main() {
//传入一个路径和一个处理器
//这个.代表的是工程目录
http.Handle("/", http.FileServer(http.Dir(".")))
http.ListenAndServe(":8080", nil)
}
2 G入门
2.1开发环境
- 安装golang
- 安装编辑器或者idea
2.2 HelloWorld
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
第一行代表属于main包,它是程序入口包,import导入fmt包,并再main函数中调用其Println函数。使用go build或go run编译或编译并运行代码
2.3 变量
go是强类型,变量都有类型。
变量的定义:
- var 关键字定义
- 自动推断类型
2.4 字符串
字符串是不可变的:指的是字符串一旦定义好,其中的字符的值不能改变
如果字符串中没有特殊字符,字符串的表示形式用双引号
如果字符串中有特殊字符,字符串的表示形式用反引号 ``
2.5 条件判断
if后无括号,写括号的话编辑器会自动去掉,且后面必须接大括号
在golang里,if后面可以并列的加入变量的定义:
switch后变量名无括号,case中不加break,且可以使用任意变量类型,当判断较多时可用switch完全替代if else
只有唯一的for循环,for中三语句任何语句都可省略且也没括号,循环中可用break或continue跳出或继续循环
2.6数组
- 一维数组
- 二维数组
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("2d: ", twoD)
}
类似其他语言中固定长度数组,实际很少使用,更多使用切片
2.7 切片
package main
import (
"fmt"
)
func main() {
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])
fmt.Println("len: ", len(s))
s = append(s, "d")
s = append(s, "e", "f", "g")
c := make([]string, len(s))
copy(c, s)
//不支持负数索引
fmt.Println(s[2:5])
fmt.Println(s[:5])
fmt.Println(s[2:])
good := []string{"1", "2", "3"}
fmt.Printf("%T", s)
good = append(good, "c")
fmt.Println(good)
}
func make(t Type, size ...IntegerType) Type函数返回切片 前者是类型后者是长度,第三个参数是初始容量 切片是一个可变长度的数组你可以任意时刻去更改长度
切片可以使用append增加元素 必须吧append结果复制给原数组 因为slice的原理 存储了长度 容量 指向数组的指针 如果容量不够数组会发生扩容
2.7 结构体方法
package main
import "fmt"
// Struct user has methods on both value and pointer receivers. Such usage is not recommended by the Go Documentation.
// 翻译 user结构体既有值接收方法也有指针接收方法
type user struct {
name string
password string
}
//在前面加一个括号变为结构体方法
func (u user) checkPassword(pwd string) bool {
return u.password == pwd
}
//在前面加一个括号变为结构体方法
func (u *user) checkPassword2(pwd string) bool {
return u.password == pwd
}
func main() {
u := user{"111", "111"}
fmt.Println(u)
fmt.Println(u.checkPassword("123"))
fmt.Println(u.checkPassword2("111"))
}
在函数名前带上结构体参数和括号,就实现类似其他语言中的类成员函数。
括号中国的结构体参数可以有两种一种是值类型,一种是指针类型
值类型会发生拷贝
2.8 错误处理
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
func findUser(users []user, name string) (u *user, err error) {
for _, user1 := range users {
if user1.name == name {
return &user1, nil
}
}
return nil, errors.New("not found")
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println("user nof find")
return
}
fmt.Println(u.name)
//if 后面定义的变量都要被用到
if u, err := findUser([]user{{"wang", "1024"}}, "wang"); err != nil {
return
} else {
fmt.Println(u.name)
}
}
go常见做法是再传递结果的返回值的基础上,新增一个传递错误信息的返回值,这样能清晰知道哪个函数出错,且能用简单的if else处理错误。使用errors.New()函数创建Error对象。
2.9 Map
var map变量名 map[keytype]valuetype
key、value的类型:bool、数字、string、指针、channel 、还可以是只包含前面几个类型的接口、结构体、数组 key通常为int 、string类型,value通常为数字(整数、浮点数)、string、map、结构体 key:slice、map、function不可以
map操作:
map["key"]= value ——》 如果key还没有,就是增加,如果key存在就是修改。
delete(map,"key") , delete是一个内置函数,如果key存在,就删除该key-value,如果k的y不存在,不操作,但是也不会报错
(1)如果我们要删除map的所有key ,没有一个专门的方法一次删除,可以遍历一下key,逐个删除 (2)或者map = make(...),make一个新的,让原来的成为垃圾,被gc回收
value ,bool = map[key] value为返回的value,bool为是否返回 ,要么true 要么false
2.10 jSON 处理
对已有结构体,保证每个字段首字母大写,是公开字段,就能用marshaler序列化变成json字符串,unmarshaler反序列化,可用json tag修改输出结果的字段名
Go实现简单抓包
选择copy as cUrl
curl 'https://api.interpreter.caiyunai.com/v1/dict' \
-H 'authority: api.interpreter.caiyunai.com' \
-H 'accept: application/json, text/plain, */*' \
-H 'accept-language: zh-CN,zh;q=0.9' \
-H 'app-name: xy' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json;charset=UTF-8' \
-H 'device-id: 69b64dcf149e14f702ddb70d7a26943a' \
-H 'origin: https://fanyi.caiyunapp.com' \
-H 'os-type: web' \
-H 'os-version;' \
-H 'pragma: no-cache' \
-H 'referer: https://fanyi.caiyunapp.com/' \
-H 'sec-ch-ua: "Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: cross-site' \
-H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36' \
-H 'x-authorization: token:qgemv4jr1y38jyq6vhvi' \
--data-raw '{"trans_type":"en2zh","source":"good"}' \
--compressed
代码生成的网址:curlconverter.com/#go
输入上述命令得到生成的代码
package main
import (
"fmt"
"io"
"log"
"net/http"
"strings"
)
func main() {
client := &http.Client{}
var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("authority", "api.interpreter.caiyunai.com")
req.Header.Set("accept", "application/json, text/plain, */*")
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
req.Header.Set("app-name", "xy")
req.Header.Set("cache-control", "no-cache")
req.Header.Set("content-type", "application/json;charset=UTF-8")
req.Header.Set("device-id", "69b64dcf149e14f702ddb70d7a26943a")
req.Header.Set("origin", "https://fanyi.caiyunapp.com")
req.Header.Set("os-type", "web")
req.Header.Set("os-version", "")
req.Header.Set("pragma", "no-cache")
req.Header.Set("referer", "https://fanyi.caiyunapp.com/")
req.Header.Set("sec-ch-ua", `"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
req.Header.Set("sec-fetch-dest", "empty")
req.Header.Set("sec-fetch-mode", "cors")
req.Header.Set("sec-fetch-site", "cross-site")
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36")
req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", bodyText)
}
JSon 转golang Struct
https://oktools.net/json2go
输入
{
"rc": 0,
"wiki": {},
"dictionary": {
"prons": {
"en-us": "[gʊd]",
"en": "[gud]"
},
"explanations": [
"a.好的;善良的;快乐的;真正的;宽大的;有益的;老练的;幸福的;忠实的;优秀的;完整的;彻底的;丰富的",
"n.利益;好处;善良;好人",
"ad.=well"
],
"synonym": [
"excellent",
"fine",
"nice",
"splendid",
"proper"
],
"antonym": [
"bad",
"wrong",
"evil",
"harmful",
"poor"
],
"wqx_example": [
[
"to the good",
"有利,有好处"
],
[
"good, bad and indifferent",
"好的,坏的和一般的"
],
[
"good innings",
"长寿"
],
[
"good and ...",
"很,颇;完全,彻底"
],
[
"do somebody's heart good",
"对某人的心脏有益,使某人感到愉快"
],
[
"do somebody good",
"对某人有益"
],
[
"be good for",
"对…有效,适合,胜任"
],
[
"be good at",
"在…方面(学得,做得)好;善于"
],
[
"as good as one's word",
"信守诺言,值得信赖"
],
[
"as good as",
"实际上,几乎等于"
],
[
"all well and good",
"也好,还好,很不错"
],
[
"a good",
"相当,足足"
],
[
"He is good at figures . ",
"他善于计算。"
]
],
"entry": "good",
"type": "word",
"related": [],
"source": "wenquxing"
}
}
结果:
type AutoGenerated struct {
Rc int `json:"rc"`
Wiki struct {
} `json:"wiki"`
Dictionary struct {
Prons struct {
EnUs string `json:"en-us"`
En string `json:"en"`
} `json:"prons"`
Explanations []string `json:"explanations"`
Synonym []string `json:"synonym"`
Antonym []string `json:"antonym"`
WqxExample [][]string `json:"wqx_example"`
Entry string `json:"entry"`
Type string `json:"type"`
Related []interface{} `json:"related"`
Source string `json:"source"`
} `json:"dictionary"`
}