一、变量

在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语言上手-基础语言相关推荐

  1. html布局语言,HTML基础语言(四)-HTML页面布局

    HTML 布局 今天写一下简单的HTML页面布局 网页布局对改善网站的外观非常重要. 所以请慎重设计您的网页布局. 网站布局大多数网站可以使用 或者 虽然我们可以使用HTML table标签来设计出漂 ...

  2. 【GitHub探索】v语言上手,用vlang写一个聊天应用

    前言 vlang(v语言)自从6月份突然炒热起来,不知不觉到了11月,正式版就要出来了,在11月的GitHub Trending榜中依然排在前10.这着实令人好奇,因此笔者决定试用一下vlang,写一 ...

  3. 什么是编程语言C语言,什么是oc语言,oc语言是c语言吗?

    作为一个ObjecTIve-C的coder,我总能听到一部分人在这门语言上抱怨有很多问题.他们总在想快速学习这门语言来写一个App出来,但他们也总是联想到ObjecTIve-C看上去实在太难了或者在想 ...

  4. c语言 字符串转运算符,快速上手系列-C语言之基础篇(二)数据类型与运算符...

    在上一篇文章<快速上手系列-C语言之基础篇(一)>中写了关于C语言的程序结构,关键字及控制语句.本篇主要写写C语言中数据类型,以及运算符相关方面的知识. 一.变量与常量 1.常量:在程序运 ...

  5. 如何学习c语言 零基础20天学会C语言

    C语言开发 学习C语言不是一朝一夕的事情,但也不需要花费十年时间才能精通.如何以最小的代价学习并精通C语言是本文的主题.请注意,即使是"最小的代价",也绝不是什么捷径,而是以最短的 ...

  6. r intersect()_30分钟掌握R语言编程基础

    R语言是世界上最广泛使用的统计编程语言.本文的目的是使得读者快速上手R语言编程. 1 R语言概述 R语言是世界上最广泛使用的统计编程语言.有人认为,它是数据科学家的第一选择(人生苦短,我选Python ...

  7. 海龟绘图两小时上手C语言 - 0 引言

    海龟绘图两小时上手C语言 0 引言 作为一名教了十几年编程的大学老师,看过不少学生一开始学习C语言,就被其复杂的语法.枯燥的数学应用案例给吓住了. 在此提供一个很简单的教程,希望零基础的读者花上两个小 ...

  8. 零基础学python还是c语言-零基础学Python之前需要学c语言吗

    Python本身是比较适合作为入门编程语言来学习的,一方面Python的语法结构比较简单清晰,实验也相对比较容易完成,这会逐渐增强初学者的学习信心,另一方面Python属于全场景编程语言,未来在很多领 ...

  9. 编程c语言零基础知识,零基础学习C语言都需要掌握哪些基础知识

    随着互联网的不断发展,越来越多的人都在学习互联网软件编程开发语言,而今天我们就一起来了解一下,零基础学习C语言都需要掌握哪些基础知识. 无论学习哪门语言先应该了解一下自己所学语言的背景,也可以说它的发 ...

最新文章

  1. 为什么要学习 Markdown?究竟有什么用?
  2. Linux awk内部变量
  3. linux 报错 E: 无法定位软件包 python-lzma
  4. JZOJ 3852. 【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
  5. Linux安装Elasticsearch-head插件
  6. 三十七、深入Python中的网络通信
  7. SAP Spartacus 服务器端 nodejs 应用里渲染 Angular Component 的一个例子
  8. Java接口能不能有静态方法_接口可以在Java中使用静态方法吗?
  9. python 数据类型之间的转换
  10. MongoDB服务重启及后台运行解决方法
  11. 如何删除office2007、以及安装新版本office
  12. 大数据平台与传统数仓的区别
  13. 别做老好人,你的善良应该带点锋芒
  14. yapi 权限_yapi部署
  15. 采用中断模式编程并使用杜邦线模拟开关实现LED灯的亮灭
  16. printf二进制输出
  17. 详解单片机中的关键字:sfr sbit
  18. [No0000158]思维模型1-20
  19. WPF与3D 模型(一)把Solidworks里的模型导入进WPF程序
  20. python3封装微信分账功能

热门文章

  1. java 记录错误日志文件_java日志记录错误的文件_方法_行号_报错信息
  2. 视频同步笔记:狂神聊Git
  3. newifi2 刷padavan 校园网认证
  4. 学籍信息管理系统--------总体设计
  5. 数学题 GDUT 院赛(数论)
  6. OpenCV矩阵运算总结
  7. 山外山通过注册:拟募资12亿 大健康与华盖信诚是股东
  8. html兼容ie的日期控件,layDate
  9. Linux操作系统实验1——地址转换
  10. 三、Zstack云平台快速安装与初始化(ZCCT云计算认证)