Go语言基础学习(1)|青训营笔记

291 阅读6分钟

这是我参与「第五届青训营 」笔记创作活动的第1天,在今天从Go语言小白,到熟悉Go语言基础语法再到使用Go语言去做一些小项目,可以说是收获满满,当然接下来我记录了一下,在课程学习之中所遇到的我认为比较重要的一些点。

一、本堂课的重点内容

今天的课程的主要知识框架为:

  • Go语言的背景介绍

    • Go语言的背景
    • Go语言的使用场景及优点
  • Go语言的快速入门

    • 开发环境的搭建
    • 基础语法讲解
    • 标准库
  • Go语言实战

    • 猜谜游戏
    • 命令行字典
    • SOCKS5代理

二、详细知识介绍

1. Go语言的背景介绍

    1.1 Go语言背景介绍

    Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。

    罗伯特·格瑞史莫(Robert Griesemer),罗布·派克(Rob Pike及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目。Go是基于Inferno操作系统所开发的。Go于2009年11月正式宣布推出,成为开放源代码项目,并在Linux及Mac OS 平台上进行了实现,后来追加了Windows系统下的实现。在2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”。 目前,Go每半年发布一个二级版本(即从a.x升级到a.y)。

    Go语言的吉祥物是一只地鼠,这个形象是由Rob Pike的妻子Renee French设计的,也就是大家看到的下面这幅图中的吉祥物。

image.png

    1.2 Go语言的适用场景及优点

        1.2.1Go语言的适用场景

        基于Go语言的创建初衷,Go语言主要应用于下述场景之中:

        · 服务器编程

        · 微服务

        · 云平台

        · Web

        · 区块链

        · 分布式

        1.2.2Go语言的优点

        ·高性能,高并发

        ·语法简单,学习曲线平缓

        ·丰富的标准库

        ·完善的工具链

        ·静态链接

        ·快速编译

        ·跨平台

        ·垃圾回收

2.Go语言快速入门

    2.1 开发环境的搭建

    对于Go语言的开发环境的搭建,对于不同的操作系统是不一样的,而我使用的是MacOS,在下载完Goland后,没有特别从外部去下载环境进行安装,这个时候也可以在Goland之中进行正常的编译运行。当然详细点的话,我看了一下网上的资料,认为这篇文章比较详细。Go语言环境的搭建

    2.2 基础语法的讲解

    对于有编程基础的开发者,从一门语言转换到另一门语言实际上是比较轻松的事情,因为基本上都是大同小异,只是一些语法风格会有所不同,对于一门语言的学习重点关注的首先是如何输入数据、如何输出数据、该语言有哪些变量类型、如何定义复杂类型、如何定义函数、该门语言的三大逻辑结构(顺序结构、分支结构和循环结构)是怎样的以及了解标准库如何使用他们。

        2.2.1 写一个Hello World

        Go语言的Hello World代码如下:

package main

import "fmt"

func main(){
    fmt.Println("Hello world!")
}

        对于上面的代码,实际上是有很多知识点在其中的。

        a.package

        对于Go语言,它是通过package包来进行代码管理的,也可以理解成一个文件夹之中可以有多个Go的源文件,而对于在同一个文件夹之中的源文件,对于每一个源文件都是可见的,并且每一个文件夹之中都只会有一个入口main包,如果在IDE之中使用多个main包并进行编译运行则会出错,这个时候如果想单独运行每一个go源文件则需要使用命令行go run 文件路径/*.go,当然也可以只编译生成二进制文件不运行,这个时候只需要使用go build 文件路径/*.go即可。

        除了main包,在同一个文件夹之下一般是定义为package 文件夹名,由于这部分的知识也相对比较多,可以查看这篇文档Go语言的package.

       b.import导入相关包

       import有点像C++的#incllude<>,当我们要使用相关的模块的时候,我们可以通过import关键字导入相关的包来使用,对于import关键字,它有很多其他的使用规则,可以查看这篇Go通过import导入包做深入了解,值得注意的是,如果导入对应的包后没有使用的话,将会报错,可能开发这门语言的人有点强迫症吧,哈哈。

        PS:如果需要查阅Go语言的标准库,可以看Go语言标准库.

       c.main函数

       这里同C/C++语言一样,其入口函数大多都是以main函数为入口函数,程序执行的时候会首先去找main函数,并通过main函数执行接下来的操作。但是这里值得注意的一个点事,代码块的大括号一定要紧接着函数后面,如下面的代码:

func main()
{
}

       这种写法是会报错的,需要特别注意。

       d.Println()Printf()的区别

       在上述代码之中我们使用的是fmt包之中的Println()方法,这个方法可以将对传入它的变量进行打印输出,它是一个可变参数函数,可以为它传入多个变量,每打印一个变量它会自动进行空格,当调用完该函数后会自动进行换行,而Printf()和C/C++语言之中的printf()是一样的,为格式化输出,对于格式化输出他的调用方式一般是Printf(“字符串/字符串+格式化输出符号",对应变量...),当执行完该函数后是不会像Peintln()一样自动进行换行的,这样便引出了转义字符的使用以及其他格式化符号的使用,当然如果需要详细了解格式化输出符号的话可以看Go语言格式化输出符号,而转义字符和咱们以前所学习的其他语言的转义字符是一样的。

        2.2.2 Go语言的变量

       a.基础类型变量

       学习一门新语言的变量无非是去了解这门语言为我们提供了怎样的变量类型,如何声明变量,对于变量的的具体类型可以查看Go基本数据类型之变量,这里值得注意的一点是,对于单个字符,如果是C/C++为我们提供了char这种数据类型,但是在Go语言之中是没有char这个关键字的,那怎么办呢?取而代之的是Go语言之中的byte或者rune这两个类型关键字,对于这两个关键字,在使用的时候byte通常用于ASCII码字符的存储,而rune通常用于Unicode的字符存储,但是咱们若直接输出(使用Println()方法)则依旧会是以数字的方式进行输出,这个时候需要通过Peintf()方法使用格式化输出符号%s进行输出才行。

        在了解Go语言所具有哪些变量之后,接下来就需要通过相应的语法规则声明一个变量,并进行使用了。变量的声明规则大致有两种,一种是非自动类型推导,另一种是自动类型推导,如下述代码所示:

// 1.非自动类型推导格式:
// 【var variableName variableType】 例如:
var numberInt int32
var numberFloat float64
var str string
// 同时可以给变量赋予一定的初值,也叫做初始化
var numberInt int32 = 2
var numberFloat float64 = 3.22
var strChar byte = 'a'
// Ps:如果不进行初始化操作的话,会默认赋予零值

// 2.自动类型推导格式:
// 【variableName := InitializeValue(必须要有)】例如:
numberIntAuto := 2
numberFloatAuto := 1.2

// 3.多变量声明-非自动类型推导格式
/*
    var(
        // 不进行初始化
        variableName variableType
        // 进行初始化
        variableName variableType = InitializeValue
        ...
    )
    例如:
*/

var(
    numberMoreInt int32
    numberMoreIntInit byte = 'a'
)

// 4.多变量声明-自动类型推导格式
/*
    var(
    variableName := InitializeValue(必须要有)
    ...
    )
    例如:
*/

var(
    numberAutoIntMore := 10
    numberAutoFloatMore := 10.2
)

        PS:对于Go语言的变量还有一个特别的匿名变量,通常用_来表示,使用的方法,通常如下述代码所示:

func test()(int,int){
    return 1,2
}

func runTest(){
    // 不想使用test寒素返回的第二个值
    a,_ := test()
}

       b.复合类型变量

       谈到复合类型变量咱们肯定会想到C/C++的结构体,没错,对于Go语言也是有结构体的,他的声明格式和上述的多变量声明有点类似,具体的声明格式为:

/*
// 声明格式为:
type complaxVariableName struct{
    variableName variableType
    ...
}
例如:
*/
type user struct{
    userName string
    password string
}

       复合类型的使用方式同基本类型的声明有一些区别,若要声明一个用户自定义类型,则使用的格式应该是structVariableName := structType{}如果采用这种方式进行声明的话那么就默认会给内部的变量以零值初始化。

       可以采用指定成员的方式进行初始化,这里以上述已有的user结构体为例,方式为a := user{userName:"a",password:"123"},采用这种方式可以是b := user{password:"123"},那么这个时候的a.userName (注意访问结构体的内部变量是采用的.运算符进行访问)将会进行零值初始化,如果是字符串则为空字符串。若采用这种方式,可以给需要的内部变量进行初始化,在后续进行操作的时候也可以直接对没有进行初始化的内部成员进行重新赋值。

       也可以直接进行初始化,这种情况下它会按照用户自定义数据类型自上而下依次去匹配,也就是是说,不能够缺省初始化,这种格式为c := user{"cc","123"}这是可以的 ,它默认会按用户自定义类型的顺序去匹配对应的成员变量进行初始化,但是若采用d := user{"dd"}则会出错,会提示用户值太少了。

       PS:值得注意的另一个点是,所有变量声明出来之后则必须使用,否则也会报错。(强迫症用户的福音)

       2.2.3Go语言的三大逻辑结构

       a. 顺序结构

        基本上每一门语言,如果没有流程控制语句的限制的话,那么默认情况下是都是从入口函数进入,依次自顶向下执行main函数的每一条语句,这就是顺序执行。

       b.分支结构——(if-else语句)

       联想到分支结构的话,其实基本上都会首先想到条件语句,在Go语言之中的条件语句的语法格式为:

/*if 【变量设定-可以不要;】条件语句{
    ...
}
例如:
*/

// 1.方式1
if i:=0;i<=0{
    ...
}

// 2.方式2
if num<=0{
    ...
}

       c.分支结构——(switch语句)

       对于Go语言的switch语句,它比C/C++语言要高级一点,首先可以缺少switch关键词后面的变量,内部的case可以改为条件语句,紧接着它也不像C/C++语句的switch语句,关键字后面的变量必须是整数值,在Go语言之中可以为任意类型,最后还有一个比较智能的点是,Go语言的switch语句每个case后面会自动追歼break语句,也就是不再像C/C++语句那样需要break关键词来防止执行接下来的语句,当然在Go语句之中也提供了fallthrough关键词用来使得继续执行下一条case语句,示例代码如下:

// 第一种情况
score := 90
switch{
    case score>=90:
         fmt.Println("A")
         fallthrough
    case score>=80:
         fmt.Println("B")
    default:
         fmt.Println("Other")
}

// 第二种情况
step := 1
switch score{
    case 1:
        fmt.Println("step 1")
    case 2:
        fmt.Println("step 2")
    default:
        fmt.Println("step other")
}

       对于上述代码,第一种情况之中的用法有点类似if-else语句,只有满足条件的case才能够执行,否则执行default,其中如果是执行到有fallthrough则会顺带执行下一条case语句.第二种情况则是我们平常使用的情况了。

       d.循环语句

       在Go语言之中的循环语句,没有while语句,也没有do-while语句,只有for循环语句,它的语法和C/C++的比较类似,只是少了一个圆括号而已,为此for的基本语法是:

/*for 初始化条件;循环条件;循环控制变量的改变{
    ...
}
例如:
*/
for i:=0;i<3;i++{
    Println(i)
}

       PS:值得注意的一个点是,自增自减运算符在Go语言之中只有后缀自增与后缀自减,不存在前缀自增和前缀自减的用法

       对于C++语言有一个基于范围的for循环,在Go语言之中也是存在这种用法的,它需要使用range关键字来进行,示例代码为:

str := "abcdef"

for i,data := range str{
    fmt.Printf("str[%d]:%c\n",i,data)
}

        使用range关键字,返回的将有两个值,第一个值为对应的下标,第二个值为遍历到的具体的数据。

三、个人总结(部分)

    在本次学习之中掌握了最基本的一些Go语言基础知识,当然在本次的学习笔记之中并没有写完,我也会在接下来的文章之中将其完善。由于部分知识后面所涉及的内容是比较多的,所以中间引用了其他专栏的相关信息。

四、参考文献

  1. 百度百科-go(计算机编程语言)
  2. Go语言环境的搭建
  3. Go语言的package
  4. Go通过import导入包
  5. Go语言标准库
  6. Go语言格式化输出符号
  7. Go基本数据类型之变量