Go语言基础 | 青训营笔记

95 阅读6分钟

这是我参与「第五届青训营 」笔记创作活动的第1天。

Go是一门高性能、高并发的静态编译型语言。在语法层面,它继承了许多语言的优点,比如C/C++的结构体,Java的垃圾回收机制等等,同时简化了语法,去除了一些语言冗杂的部分。 由于大部分语法和其他语言相似,故不详细介绍。我着重挑对我印象深刻的部分列举。

一、从一个hello world中认识go

main包表示这个文件属于main包的一部分,main包也就是程序的入口

package main

import导入软件包,这个括号是装载多个库的意思,用字符串写每个库的名字比如“fmt",不需要逗号

import (
   "fmt"  //这个包主要用来输入输出字符串,格式化字符串
   "math" //一些数学处理方法
)

这是main函数,要注意,go语言不用显式的在文末加上分号,并且大括号必须不能单独起行,那么问题来了,这是为什么呢? 看GO圣经里的解释:

当输入被断开为标记时,如果行末标记为:

  a. 一个标识符
  b. 一个整数、浮点数、虚数、字符或字符串文字
  c. 关键字breakcontinue、fallthrough或return中的一个
  d. 运算符和分隔符++、--、)、]或}中的一个
  则分号将被自动插入到标记流中非空白行的末尾
func main() {
    fmt.println("hello world")
}

好了,到这里,一个hello world完成了,你有以下两种编译运行方式:

go run 路径+文件名 编译运行文件

go build ……则是二进制形式编译运行

二、变量

go是强类型语言,但能自己解析变量类型 变量声明有两种形式, 一种是var name string ="",比如var b int = 6。声明变量的时候,一般会自动推到变量的类型,也可以”显式“的写出变量类型。 第二种声明方式。变量名name 冒号:=等于 要给的值,这种方式就是必须要初始化

go的字符串是内置类型,可以直接通过加号拼接,也能直接用等于号去比较字符串

var a = "initial"

也可以一次定义多个变量 有需要的话在变量名后面可以”显式“的加上类型 可以看到多个变量初始化时可以直接用一个等于号按顺序赋值给多个变量,不需要其他语言一个一个赋值

var b, c int = 1, 2

这种是bool类型

var d = true

强制类型转换成float32

var e float64
f := float32(e)

go的字符串是内置类型,可以直接通过加号拼接,也能直接用双等于号==去比较字符串

g := a + "foo"

三、循环

go里面没有while和do-while,只有for

go的for条件不需要括号

最简单的for可以什么都不写,代表一个死循环

i := 1
for {
   fmt.Println("loop")
   break //break跳出循环
}

for n := 0; n < 5; n++ {
   if n%2 == 0 {
      continue //continue跳过剩下的部分开始下一轮循环的迭代
   }
   fmt.Println(n)
}

最常见的for循环

for j := 7; j < 9; j++ {
   fmt.Println(j)
}

这是for套皮的while

for i <= 3 {
   fmt.Println(i)
   i = i + 1
}

四、if-else和switch-case

(1)if-else注意即使是一行也需要大括号

(2)go的swtich条件也不需要括号,go的switch和c/cpp不同的地方在于,c不显式的加break会一直执行下去,go不需要break也会在运行完一个case分支后自动跳出。go的swtich很强大,可以使用任意类型。go的swtich代替任意的if-else,优点是这样比if-else代码逻辑更清晰

五、数组、切片和map

和python差不多,这里不详细介绍

六、函数和指针

go也支持指针哦。

go实现两个变量相加的函数。 和其他语言不一样的是,go的变量类型是后置的

func 函数名(参数名 参数类型,……) 函数返回值类型 {
    函数体
}

七、结构体

结构体是带类型的字段的集合

type user struct {
   name     string
   password string
}

结构体---可以看作面向对象的类,包括属性(普通变量字段)+方法(结构体方法)

结构体方法---可以看作类成员的方法

在实现结构体的方法的时候也可以有两种写法,一种是带指针,一种是不带指针。他们的区别是如果带指针,那么就可以对这个结构体去修改。

如果不带指针,实际上操作是一个拷贝,就无法对结构体进行修改。

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

用法和python差不多,不过多赘述了。

八、error

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

不同于Java自家使用的异常,go语言的处理方式,能够很清晰的知道哪个函数返回了错误,并且能用简单的if-else来处理错误。(java则是try-catch)

在函数里,我们可以在哪个函数的返回值类型里面,后面加一个error,就代表这个函数可能会返回错误。 那么在函数实现的时候,return需要同时返回两个值, 要么就是如果出现错误的话,可以return nil和一个error。 如果没有的话,那么返回原本的结果和nil

九、项目

guessing-game

主要是用了随机数种子和随机数生成函数。用二分法能很快猜出来。

func main() {
   maxNum := 100
   rand.Seed(time.Now().UnixNano())
   secretNumber := rand.Intn(maxNum)
   fmt.Println("The secret number is ", secretNumber)
}

simpledict

在线小词典主要是抓包,调用词典api,发出post请求和接它的响应,以及json格式处理的问题!然后把接收到的json数据打印出来。

proxy

做一个SOCKS5代理服务器实现传输数据。需要计网的知识,有空再回头复现。

其他注意点:

1、go的时间格式化为 2006-01-02 15:04:05这个模板。 2、要会用字符串处理的各种方法。 3、go可以只用v格式化输出所有类型:

    %v 只输出所有的值  
    %+v 先输出字段类型,再输出该字段的值  
    %#v 先输出结构体名字值,再输出结构体

……and so on。

引用参考:

go语言中换行和分号那点事------理解为什么:t.csdn.cn/wrRc4