🌈Go语言-零基础入门教程(学习笔记)|Go主题月

1,010 阅读11分钟

〇、声明

教程名称:《Go语言-零基础入门教程》
教程出处:1024课堂
教程地址:1024casts.com/courses/go-… go.jpg   本文性质为个人学习笔记,是笔者学习教程的笔记和心得,如有疑问,敬请指正。 本文为全书笔记,分为多个章节,对于比较长篇幅的小节笔记拆分为独立的小节笔记,并通过连接方式添加到本文。

  笔者熟悉 C# 和 JavaScript,在学习 Go 的过程中会时长与 C# 和 JavaScript 作比较,如果有对相关语言理解错误的地方请多指正,共同成长。学习顺序和原视频教程略有不同,同时也夹杂着视频以外的知识点。如果读者觉得不够循序渐进可以直接学习原视频。

  人穷志不短,虽然买不起 Mac OS X,但用 Windows 也很好学,下载 Go>>

一、基本介绍

1.1 Go 语言简史

  语言入门第一章一般都是要先介绍语言的创始者,我们换换场子……先。

1.1.1 语言诞生年份

序号语言年份
1C1970
2C++1979-1983
3R1980
4Python1990
5Visual Basic1991
6JavaScript1995
7PHP1995
8Java1995
9C#2000
10Go2009

1.1.2 Go 的诞生

  每个语言诞生都有属于他的故事和目的,了解故事的背景有助于体悟语言本身存在的意义。那么什么是数据 Go 的故事呢? google.jpg   要说起 Go 语言,不得不说他有个好爹,大将之子,名门之后,绝对一身好血统,说起他爹大家一定都很熟悉,那就是 Google(当然,他也有个很有名的儿子 Docker)。调查结果显示,2019 年,程序员最想学习的编程语言 Top 3 分别是 Go、Kotlin 和 Python,其中 Go 以 37.2% 的比例排在首位。 docker.png   Go 语言自己应该是不知道他有多可爱,但作为他生身之父的 Google 自然懂得。

  1. 计算机硬件技术更新频繁,性能提高很快。目前主流的编程语言发展明显落后于硬件,不能合理利用多核多CPU的优势提升软件系统性能。
  2. 软件系统复杂度越来越高,维护成本越来越高,目前缺乏一个足够简洁高效的编程语言。
    现有的编程语言:
    • 风格不统一
    • 计算能力不够
    • 处理大并发不够好
  3. 企业运行维护很多 C/C++ 的项目,C/C++ 程序运行速度虽然很快,但是编译速度却很慢,同时还存在内存泄漏的一系列的困扰需要解决

其实我也不知道,抄来的,转载信息见本章最后一节。
同时,关于 Go 语言特性方面将在下一章介绍(其实我还没学废)
O(∩_∩)O哈哈~

1.1.3 Go 语言用途

  Go 语言保证了既能达到静态编译语言的安全和性能,又达到了动态语言开发维护的高效率,使用一个表达式来形容 Go 语言:Go = C + Python,说明 Go 语言既有 C 静态语言程序的运行速度,又能达到 Python 动态语言的开发。

  Go 语言的目标是希望提升现有编程语言对程序库等依赖性(dependency)的管理,这些软件元素会被应用程序反复调用。由于存在并行编程模式,因此这一语言也被设计用来解决多处理器的任务。

  Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。

1.1.4 本章参考

1.2 语言特性

  Go 语言具有众多语言特性,下面就其中几个优秀且具有代表性的特性简单谈谈。

1.2.1 垃圾回收机制

  说起垃圾回收功能,不得不把 C/C++ 拿出来和 C#、Java、Python 比较。

  垃圾回收可能会带来严重的空间和时间开销,实现和移植垃圾回收会使得语言本身设计更复杂。还有,垃圾回收将使语言不适合做许多底层的工作,而这却正是 C/C++ 的一个设计目标。虽然 C/C++ 没有垃圾回收机制,但是 C++ 的设计者 Bjarne Stroustrup 说过,他喜欢垃圾回收的思想,“它是一种机制,能够简化设计、排除掉许多产生错误的根源。需要垃圾回收的基本理由是很容易理解的:用户的使用方便以及比用户提供的存储管理模式更可靠。”(参见The Design and Evolution of C++(豆瓣)

  我们再说说 C# 的垃圾回收机制,说 C# 得先说说 .NET Framework(框架)、LI(中间语言)、CLR(公共语言运行时),CLR 是 .NET Framework 的一部分,C#、VB 等使用 .NET Framework 提供的编译器编译成 LI 语言在 CLR 上运行。CLR 和 Java 虚拟机相类似,.NET Framework 把资源分为托管资源和非托管资源,由 CLR 管理的存在于托管堆上的称为托管资源,非托管资源是不由 CLR 管理的,是否托管资源类型是固定的(这里不作介绍)。于是,托管资源就由 CG(垃圾回收器)在 CLR 觉得合适的时候进行回收,非托管资源不会自动回收,需要开发者自定义代码进行资源回收处理。

  Java 的垃圾回收机制是完全自动的,java 堆内存的时候调用垃圾回收机制,也可以通过代码调用 GC 方法提示虚拟机进行垃圾回收,但也不会马上进行垃圾回收。但是 Java 也有内存资源和非内存资源的概念,非内存资源不受垃圾回收机制管控,需要通过代码人工处理,比如文件的 Close()。

  Python 的垃圾回收机制也是完全自定的,当然也可以通过代码人工触发垃圾回收,和 Java 的最大区别应该是,Python 所谓万物皆对象,没有所谓非内存需要人工关闭回收的说法。Python 垃圾回收机制

  曾几何时,内存管理是程序员开发应用的一大难题。传统的系统级编程语言(主要指C/C++)中,程序员必须对内存小心的进行管理操作,控制内存的申请及释放。稍有不慎,就可能产生内存泄露问题,这种问题不易发现并且难以定位,一直成为困扰开发者的噩梦。言归正传,Go 语言作为现代语言,GC 必不可少,Go 的 GC 模式和 Python 非常相近,而在 Go 的发展历程中,GC 功能一度成为 Go 的吐槽对象(好好吧,我也是听来的,不多说)

笔者了解还不够,也就不深入介绍了,如果上述描述有误还请留言指正,谢谢!

1.2.2 内置数据类型

  首先,说说强类型和弱类型。Go 语言是强静态类型,下面简单列出编程语言类型划分:

  • 动态典型: Python, Ruby, PHP, JavaScript, VBScript
  • 静态典型: C/C++, C#, Java, Go
  • 强定义典型: C/C++, C#, Java, Go
  • 弱定义典型: PHP, Asp, Ruby, Python, ABAP, Javascript, Unix shell

  其实对于静态类型的语言中,也并非不会出现动态类型,比如 C# 在 .NET 4.0 以后就有了 dynamic 类型,dynamic 类型可以是任何类型,运行时确认具体类型,类似于 JavaScript 中始终用 var 定义变量,var 可以在运行中实时更改成新的类型。

  很多教程和博文中都把内置数据类型作为 Go 的一大语言特性,但是并没有明确原有。笔者为什么要有次疑问呢?因为现如今熟知的语言大多包含全面的数据类型,在没有明确说明 Go 的内置数据类型有什么特别之处的情况下,这一点被提及就缺少点价值了。

  其次,Go 语言具有更多的内置数据类型,仅整形就有这些划分:uint8uint16uint32uint64uintint8int16int32int64int。(其实如 C# 也是有很多种类型),类型的种类更多,可供随意挑选(但是设计者绝对没有考虑过重度选择恐惧症程序员们的心情)。但是类型多并不代表你可以随性所欲,比如在实际项目中,类型的设定往往和数据库相关(仅使用数据库或数据库连接类相匹配的类型),也往往需要考虑业务对接时候第三方的类型设定,总之,更多的选择并不代表你用友了更多的自由。【Go】那么多数值类型,应该选哪个?

1.2.3 函数多返回值

  多返回值的设计确实很有意思,不少语言的设计都只有单返回值,比如 C#,但是随着语言及开发需求的发展,C#也添加了支持多返回的方式(通过参数作返回),而且还支持 in, out 双向模式的 ref(引用),下面是 C# 的方法:

/// <summary>
/// 多返回测试
/// </summary>
/// <param name="context1"></param>
/// <param name="context2"></param>
/// <returns></returns>
public string FuncTowReturn(out string context1, out string context2)
{
    context1 = "扩展返回1";
    context2 = "扩展返回2";
    return "默认返回";
}

/// <summary>
/// 传引用
/// </summary>
/// <param name="context1"></param>
/// <param name="context2"></param>
/// <returns></returns>
public string FuncRef(ref string context1, ref string context2)
{
    context1 = "修改扩展返回1";
    context2 = "修改扩展返回2";
    return "新的默认返回";
}

/// <summary>
/// 测试
/// </summary>
public void Demo()
{
    string str1, str2;
    var str0 = FuncTowReturn(out str1, out str2);
    Console.WriteLine($"方法 FuncTowReturn 有多个返回,分别是{str0},{str1},{str2}");

    str0 = FuncRef(ref str1, ref str2);
    Console.WriteLine($"方法 FuncRef 单返回,单额外通过引用修改参数值,返回分别是{str0},{str1},{str2}");
}

  而 Go 语言本身就设计了多返回,而不是通过参数方式实现,下面给出一个简单的例子(摘抄自《Go 语言圣经》多返回值),不需要深究,看看结构就好!

func main() {
    for _, url := range os.Args[1:] {
        links, err := findLinks(url)
        if err != nil {
            fmt.Fprintf(os.Stderr, "findlinks2: %v\n", err)
            continue
        }
        for _, link := range links {
            fmt.Println(link)
        }
    }
}

// findLinks performs an HTTP GET request for url, parses the
// response as HTML, and extracts and returns the links.
func findLinks(url string) ([]string, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    if resp.StatusCode != http.StatusOK {
        resp.Body.Close()
        return nil, fmt.Errorf("getting %s: %s", url, resp.Status)
    }
    doc, err := html.Parse(resp.Body)
    resp.Body.Close()
    if err != nil {
        return nil, fmt.Errorf("parsing %s as HTML: %v", url, err)
    }
    return visit(nil, doc), nil
}

1.2.4 错误处理

1.2.5 匿名函数和闭包

1.2.6 类型和接口

  1. struct关键字
  2. 不支持集成和重载
  3. 支持类型组合
  4. 接口

1.2.7 并发编程

  1. goroutine(go 关键字)
  2. channel
  3. 使用“消息传递”来共享内存,非使用“共享内存”来通信

1.2.8 反射

1.2.9 语言交互性

  1. Go和C有着天然的联系
  2. Cgo 工具

2021-03-25 13:00 本小节对应视频知识点比较概括,笔记暂写到这,准备查阅额外资料进行补偿描述

1.3. Go 程序 Hello World

来一段我们经典代码吧:

package main

import "fmt"

func main() {
   /* 这是我的第一个简单的程序 */
   fmt.Println("你好, 🌈彩虹兄弟!")
}

运行结果如下:

PS D:\Temp\Golang> go run GoFirst
你好, 🌈彩虹兄弟!
PS D:\Temp\Golang> 

二、环境搭建

基础语法

1. 变量

2. 常量

3. 类型 - 基础类型和复合类型

4. 基础类型之布尔类型

5. 基础类型之整形

6. 基础类型之浮点型

7. 基础类型之字符串(上)

8. 基础类型之字符串(下)

9. 数组 - 固定大小的连续空间

10. 切片 slice - 动态分配大小的连续空间

11. 字典 map - 建立事物关联的容器

流程控制

1. 流程控制之条件语句

2. 流程控制之选择语句

3. 流程控制之循环语句

4. 流程控制之跳转语句

函数

1. 函数定义

2. 函数调用

3. 不定参数

4. 多返回值

5. 匿名函数与闭包

错误处理

1. error 接口

2. defer - 延迟执行语句

3. panic - 程序终止运行

4. recevor - 防止程序奔溃