Go语言上手-基础语言
一、变量
在Golang中,定义变量使用:=或者var i
Golang是强类型语言,必须声明变量类型(或初始化过程中获得类型)。
var a = "initial" //初始化获得类型var b, c int = 1, 2 //提前声明类型var d = true //初始化获得类型var e float64 //提前声明类型f := float32(e) //初始化获得类型
二、条件语句
在Golang中,if else的 使用类似于C++、Java等,但不需要小括号包裹条件。
if 7%2 == 0 {fmt.Println("7 is even")
} else {fmt.Println("7 is odd")
}
但在Golang中,if中可以添加一些前置条件
if num := 9; num < 0 {fmt.Println(num, "is negative")
} else if num < 10 {fmt.Println(num, "has 1 digit")
} else {fmt.Println(num, "has multiple digits")
}
三、循环语句
Golang中只有for循环
1、无限制条件
for {fmt.Println("loop")break
}
这种默认为恒成立
2、有限制条件
for i <= 3 {fmt.Println(i)i = i + 1
}
这种类似于C++、Java中的while循环
3、有前置语句,循环语句和循环语句
for j := 7; j < 9; j++ {fmt.Println(j)
}
这种类似于C++、Java中的fori循环
4、continue、break
continue和break的用法与C++、Java相同
for n := 0; n < 5; n++ {if n%2 == 0 {continue}fmt.Println(n)
}
四、分支结构
switch a {case 1: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")
}
在Golang中,switch执行完一个case后默认会跳出switch,不会继续执行。变量名也不用添加括号。
也可以使用任意的数据类型,例如字符串等等。
五、数组
数组是一个可以存放多个相同类型数据的结构。
var a [5]int
a[4] = 100
可以很轻松的使用索引来使用数组中的值
fmt.Println("len:", len(a))
可以通过len()来获取数组的长度。
在golang中,数组的长度是不可变的。
六、切片
切片是一种可变长度的数组。
创建
可以使用make进行创建
s := make([]string, 3)
这里就创建了一个string类型的切片,初始容量为3
使用
切片的使用类似于数组
s[0] = "a"
s[1] = "b"
s[2] = "c"
追加元素
s = append(s, "d")
s = append(s, "e", "f")
追加之后需要赋值给原来的切片
拷贝
copy(c, s)
切片可以通过copy进行拷贝复制
截取
fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5]) // [a b c d e]
fmt.Println(s[2:]) // [c d e f]
切片可以通过:索引的方式来获取其中的值(通常也是删除切片中元素的方式)
七、map
存储key-value类型的数据。在golang中,map是完全无序的,输出是纯随机的。
创建
通过make进行创建
m := make(map[string]int)
使用
m["one"] = 1
m["two"] = 2
获取map里面的值
r, ok := m["unknow"]
这里的r是取出来的值,ok是是否取出
删除
使用delete进行删除
delete(m, "one")
八、range
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {sum += numif num == 2 {fmt.Println("index:", i, "num:", num) // index: 0 num: 2}
}
range遍历会返回两个值,第一个是索引,第二个是遍历的值
九、函数
golang中函数是可以返回多个值的,通常情况下,第一个是用的值,第二个是是否成功或者说存在。
定义方式
func 函数名(参数) 返回值类型 {return 返回值
}
func add(a int, b int) int {return a + b
}func add2(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
}
十、指针
在golang中,指针的操作并不如C、C++中那么灵活,一般只是用来对传入的参数进行修改。
func add2(n int) {n += 2
}func add2ptr(n *int) {*n += 2
}
例如这里,上面这种方式是无法对n进行修改的,下面这种方式通过指针就可以实现。
十一、结构体
结构体是带类型的字段的集合
type user struct {name stringpassword string
}
创建一个结构体变量
可以通过结构体名来创建
a := user{name: "wang", password: "1024"}
b := user{"wang", "1024"}
c := user{name: "wang"}
第一种通过键值对的方式,值一一对应
第二种按照结构体中的顺序对应
第三种缺少的如果结构体中有默认就为默认,没有则为空
使用
结构体中的数据,可以通过.来进行使用
d.name = "wang"
d.password = "1024"
结构体方法
在golang中,可以为结构体定义一些方法
类似于在面向对象中的成员方法,这里可以使用.对方法进行调用
func checkPassword(u user, password string) bool {return u.password == password
}func checkPassword2(u *user, password string) bool {return u.password == password
}
十二、错误处理
在golang中,通常使用函数的返回值来返回错误信息,然后可以通过if else来轻松对异常进行处理
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {fmt.Println(err)return
}
fmt.Println(u.name) // wangif u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {fmt.Println(err) // not foundreturn
} else {fmt.Println(u.name)
}
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")
}
这里就利用errors.New创建了一个错误
十三、string操作
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([]string{"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", "-")) // [a b c]
fmt.Println(strings.ToLower(a)) // hello
fmt.Println(strings.ToUpper(a)) // HELLO
fmt.Println(len(a)) // 5
Contains
判断字符串中是否有对应的子字符串
Count
返回字符串中对应字串的数量
HasPrefix
从前往后判断字符串中是否有对应的子字符串
HasSuffix
从后往前判断字符串中是否有对应的子字符串
Index
查找某个字符串的位置(返回首个字符出现的位置)
Join
连接多个字符串,可以接收string类型的切片和string
Repeat
重复一个字符串多次,并拼接
Split
通过后面的字符串去切割字符串
ToLower
将字符串小写
ToUpper
将字符串大写
字符串格式化
fmt.Println(s, n)
多个变量之间空格,打印完换行
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}
%v使用不同的前缀,可以获得不同的输出结果,根据需要选择
十四、json处理
在golang中,将结构体转换为json格式的字符串,要保证结构体中的每个字段的首字母大写(公开)
通过json.Marshall进行序列化,然后通过string()将其转换为字符串
可以使用json.Unmarshall将其反序列化到一个结构体变量中
当我们需要一个不同名字的json时,可以使用json:"名字"
将其转换为对应的名字
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
err = json.Unmarshal(buf, &b)
if err != nil {panic(err)
}
十五、时间处理
time.Now()
获取当前时间
time.Date()
构造一个带时区的时间
可以通过.来获取时间点的一些信息,如年月日等。
Sub
对两个时间进行相减
格式化
运用一个具体时间
Format或者Parse进行
Unix
获取时间戳
now := time.Now()
fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
t2 := time.Date(2022, 3, 27, 2, 30, 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
fmt.Println(t.Format("2006-01-02 15:04:05")) // 2022-03-27 01:25:36
diff := t2.Sub(t)
fmt.Println(diff) // 1h5m0s
fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
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) // true
fmt.Println(now.Unix()) // 1648738080
十六、数字解析
在strconv包下面,可以使用这个包进行对应的转换
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) // 1.234n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n) // 111n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n) // 4096n2, _ := strconv.Atoi("123")
fmt.Println(n2) // 123n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
第一个参数是对应字符串,第二个参数是进制(0为自动推断),也可以用Atoi来进行一个快速转换
字符串中的如果不合法就会返回错误err
十七、进程信息
// 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]
fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
fmt.Println(os.Setenv("AA", "BB"))buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {panic(err)
}
fmt.Println(string(buf)) // 127.0.0.1 localhost
可以获取一些进程的相关参数
可以使用Getenv获取环境变量,可以通过Setenv设置环境变量。启动子进程并且输入输出exec.Command。
十八、猜谜游戏实战
package mainimport ("fmt""math/rand""time"
)func main() {maxNum := 100rand.Seed(time.Now().Unix())randNum := rand.Intn(maxNum)fmt.Println("Please input your guess")for {var guessNum int_, err := fmt.Scanf("%v\n", &guessNum)if err != nil {fmt.Println("Invalid input.Please enter an integer value")continue}if guessNum > randNum {fmt.Println("Your guess is bigger than the secret number,please input another")} else if guessNum < randNum {fmt.Println("Your guess is smaller than the secret number,please input another")} else {fmt.Println("Wow,Your guess is right")break}}
}
十九、在线词典
package mainimport ("encoding/json""fmt""io/ioutil""log""net/http""strings"
)type DictResponse struct {Rc int `json:"rc"`Wiki struct {KnownInLaguages int `json:"known_in_laguages"`Description struct {Source string `json:"source"`Target interface{} `json:"target"`} `json:"description"`ID string `json:"id"`Item struct {Source string `json:"source"`Target string `json:"target"`} `json:"item"`ImageURL string `json:"image_url"`IsSubject string `json:"is_subject"`Sitelink string `json:"sitelink"`} `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"`
}func query(word string) {client := &http.Client{}var data = strings.NewReader(`{"trans_type":"en2zh","source":"` + word + `"}`)req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)if err != nil {log.Fatal(err)}req.Header.Set("Accept", "application/json, text/plain, */*")req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")req.Header.Set("Connection", "keep-alive")req.Header.Set("Content-Type", "application/json;charset=UTF-8")req.Header.Set("Origin", "https://fanyi.caiyunapp.com")req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")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/100.0.4896.75 Safari/537.36")req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")req.Header.Set("app-name", "xy")req.Header.Set("os-type", "web")req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"`)req.Header.Set("sec-ch-ua-mobile", "?0")req.Header.Set("sec-ch-ua-platform", `"Windows"`)resp, err := client.Do(req)if err != nil {log.Fatal(err)}defer resp.Body.Close()bodyText, err := ioutil.ReadAll(resp.Body)if err != nil {log.Fatal(err)}if resp.StatusCode != 200 {log.Fatal("bad StatusCode", resp.StatusCode, "body", string(bodyText))}var dictResponse DictResponsejson.Unmarshal(bodyText, &dictResponse)if err != nil {log.Fatal(err)}fmt.Println("UK", dictResponse.Dictionary.Prons.En, "US", dictResponse.Dictionary.Prons.EnUs)for _, item := range dictResponse.Dictionary.Explanations {fmt.Println(item)}
}func main() {var s stringfmt.Scan(&s)query(s)
}
二十、代理服务器
package mainimport ("bufio""context""encoding/binary""errors""fmt""io""log""net"
)const socks5Ver = 0x05
const cmdBind = 0x01
const atypIPV4 = 0x01
const atypeHOST = 0x03
const atypeIPV6 = 0x04func main() {server, err := net.Listen("tcp", "127.0.0.1:1081")if err != nil {panic(err)}for {client, err := server.Accept()if err != nil {log.Printf("Accept failed %v", err)continue}go process(client)}
}func process(conn net.Conn) {defer conn.Close()reader := bufio.NewReader(conn)err := auth(reader, conn)if err != nil {log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)return}err = connect(reader, conn)if err != nil {log.Printf("client %v auth failed:%v", conn.RemoteAddr(), err)return}
}func auth(reader *bufio.Reader, conn net.Conn) (err error) {// +----+----------+----------+// |VER | NMETHODS | METHODS |// +----+----------+----------+// | 1 | 1 | 1 to 255 |// +----+----------+----------+// VER: 协议版本,socks5为0x05// NMETHODS: 支持认证的方法数量// METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。RFC预定义了一些值的含义,内容如下:// X’00’ NO AUTHENTICATION REQUIRED// X’02’ USERNAME/PASSWORDver, err := reader.ReadByte()if err != nil {return fmt.Errorf("read ver failed:%w", err)}if ver != socks5Ver {return fmt.Errorf("not supported ver:%v", ver)}methodSize, err := reader.ReadByte()if err != nil {return fmt.Errorf("read methodSize failed:%w", err)}method := make([]byte, methodSize)_, err = io.ReadFull(reader, method)if err != nil {return fmt.Errorf("read method failed:%w", err)}// +----+--------+// |VER | METHOD |// +----+--------+// | 1 | 1 |// +----+--------+_, err = conn.Write([]byte{socks5Ver, 0x00})if err != nil {return fmt.Errorf("write failed:%w", err)}return nil
}func connect(reader *bufio.Reader, conn net.Conn) (err error) {// +----+-----+-------+------+----------+----------+// |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |// +----+-----+-------+------+----------+----------+// | 1 | 1 | X'00' | 1 | Variable | 2 |// +----+-----+-------+------+----------+----------+// VER 版本号,socks5的值为0x05// CMD 0x01表示CONNECT请求// RSV 保留字段,值为0x00// ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型。// 0x01表示IPv4地址,DST.ADDR为4个字节// 0x03表示域名,DST.ADDR是一个可变长度的域名// DST.ADDR 一个可变长度的值// DST.PORT 目标端口,固定2个字节buf := make([]byte, 4)_, err = io.ReadFull(reader, buf)if err != nil {return fmt.Errorf("read header failed:%w", err)}ver, cmd, atyp := buf[0], buf[1], buf[3]if ver != socks5Ver {return fmt.Errorf("not supported ver:%v", ver)}if cmd != cmdBind {return fmt.Errorf("not supported cmd:%v", ver)}addr := ""switch atyp {case atypIPV4:_, err = io.ReadFull(reader, buf)if err != nil {return fmt.Errorf("read atyp failed:%w", err)}addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3])case atypeHOST:hostSize, err := reader.ReadByte()if err != nil {return fmt.Errorf("read hostSize failed:%w", err)}host := make([]byte, hostSize)_, err = io.ReadFull(reader, host)if err != nil {return fmt.Errorf("read host failed:%w", err)}addr = string(host)case atypeIPV6:return errors.New("IPv6: no supported yet")default:return errors.New("invalid atyp")}_, err = io.ReadFull(reader, buf[:2])if err != nil {return fmt.Errorf("read port failed:%w", err)}port := binary.BigEndian.Uint16(buf[:2])dest, err := net.Dial("tcp", fmt.Sprintf("%v:%v", addr, port))if err != nil {return fmt.Errorf("dial dst failed:%w", err)}defer dest.Close()log.Println("dial", addr, port)// +----+-----+-------+------+----------+----------+// |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |// +----+-----+-------+------+----------+----------+// | 1 | 1 | X'00' | 1 | Variable | 2 |// +----+-----+-------+------+----------+----------+// VER socks版本,这里为0x05// REP Relay field,内容取值如下 X’00’ succeeded// RSV 保留字段// ATYPE 地址类型// BND.ADDR 服务绑定的地址// BND.PORT 服务绑定的端口DST.PORT_, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0})if err != nil {return fmt.Errorf("write failed: %w", err)}ctx, cancel := context.WithCancel(context.Background())defer cancel()go func() {_, _ = io.Copy(dest, reader)cancel()}()go func() {_, _ = io.Copy(conn, dest)cancel()}()<-ctx.Done()return nil
}
Go语言上手-基础语言相关推荐
- html布局语言,HTML基础语言(四)-HTML页面布局
HTML 布局 今天写一下简单的HTML页面布局 网页布局对改善网站的外观非常重要. 所以请慎重设计您的网页布局. 网站布局大多数网站可以使用 或者 虽然我们可以使用HTML table标签来设计出漂 ...
- 【GitHub探索】v语言上手,用vlang写一个聊天应用
前言 vlang(v语言)自从6月份突然炒热起来,不知不觉到了11月,正式版就要出来了,在11月的GitHub Trending榜中依然排在前10.这着实令人好奇,因此笔者决定试用一下vlang,写一 ...
- 什么是编程语言C语言,什么是oc语言,oc语言是c语言吗?
作为一个ObjecTIve-C的coder,我总能听到一部分人在这门语言上抱怨有很多问题.他们总在想快速学习这门语言来写一个App出来,但他们也总是联想到ObjecTIve-C看上去实在太难了或者在想 ...
- c语言 字符串转运算符,快速上手系列-C语言之基础篇(二)数据类型与运算符...
在上一篇文章<快速上手系列-C语言之基础篇(一)>中写了关于C语言的程序结构,关键字及控制语句.本篇主要写写C语言中数据类型,以及运算符相关方面的知识. 一.变量与常量 1.常量:在程序运 ...
- 如何学习c语言 零基础20天学会C语言
C语言开发 学习C语言不是一朝一夕的事情,但也不需要花费十年时间才能精通.如何以最小的代价学习并精通C语言是本文的主题.请注意,即使是"最小的代价",也绝不是什么捷径,而是以最短的 ...
- r intersect()_30分钟掌握R语言编程基础
R语言是世界上最广泛使用的统计编程语言.本文的目的是使得读者快速上手R语言编程. 1 R语言概述 R语言是世界上最广泛使用的统计编程语言.有人认为,它是数据科学家的第一选择(人生苦短,我选Python ...
- 海龟绘图两小时上手C语言 - 0 引言
海龟绘图两小时上手C语言 0 引言 作为一名教了十几年编程的大学老师,看过不少学生一开始学习C语言,就被其复杂的语法.枯燥的数学应用案例给吓住了. 在此提供一个很简单的教程,希望零基础的读者花上两个小 ...
- 零基础学python还是c语言-零基础学Python之前需要学c语言吗
Python本身是比较适合作为入门编程语言来学习的,一方面Python的语法结构比较简单清晰,实验也相对比较容易完成,这会逐渐增强初学者的学习信心,另一方面Python属于全场景编程语言,未来在很多领 ...
- 编程c语言零基础知识,零基础学习C语言都需要掌握哪些基础知识
随着互联网的不断发展,越来越多的人都在学习互联网软件编程开发语言,而今天我们就一起来了解一下,零基础学习C语言都需要掌握哪些基础知识. 无论学习哪门语言先应该了解一下自己所学语言的背景,也可以说它的发 ...
最新文章
- 为什么要学习 Markdown?究竟有什么用?
- Linux awk内部变量
- linux 报错 E: 无法定位软件包 python-lzma
- JZOJ 3852. 【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- Linux安装Elasticsearch-head插件
- 三十七、深入Python中的网络通信
- SAP Spartacus 服务器端 nodejs 应用里渲染 Angular Component 的一个例子
- Java接口能不能有静态方法_接口可以在Java中使用静态方法吗?
- python 数据类型之间的转换
- MongoDB服务重启及后台运行解决方法
- 如何删除office2007、以及安装新版本office
- 大数据平台与传统数仓的区别
- 别做老好人,你的善良应该带点锋芒
- yapi 权限_yapi部署
- 采用中断模式编程并使用杜邦线模拟开关实现LED灯的亮灭
- printf二进制输出
- 详解单片机中的关键字:sfr sbit
- [No0000158]思维模型1-20
- WPF与3D 模型(一)把Solidworks里的模型导入进WPF程序
- python3封装微信分账功能