Golang 入门:初学者教程

2025-06-08

Golang 入门:初学者教程

Golang,也称为 Go,是一种开源编程语言,由 Google 开发人员 Robert Griesemer、Ken Thompson 和 Rob Pike 于 2007 年创建。它以简单为目的,许多开发人员称赞它可以构建简单、可靠的程序。

自发布以来,Golang 的受欢迎程度日益提升。2009 年和 2016 年,它被评为年度语言。2018 年,它位列第十,并持续在各大组织中崭露头角

这门语言有很多优势。任何想在谷歌工作的人都应该了解这门语言。所以今天,我想带你深入学习 Go 编程语言。

今天我们将讨论:

  • Golang 特性概述
  • Go 的基本术语和概念
  • Go 的中级概念
  • Go 的高级概念
  • 资源

替代文本

Golang 特性概述

这种通用编程语言包含许多其他编程语言的优秀特性。它具有编译性、简洁性、并发性、静态类型和高效性。Go 改进了编程语言的这些方面,并简化了开发人员的工作环境。

Go 本质上是一种兼容并发概念的命令式语言。它保留了面向对象编程的一些优秀特性,例如接口,但也避免了一些陷阱。Go​​ 的设计初衷是摒弃面向对象编程中一些“重量级”的特性。

从这个方面来说,Go 是混合型的,它利用多种语言的最佳特性,具有清晰、富有表现力的类型系统,同时保持轻量级且易于学习。

Go 可用于各种软件开发解决方案,例如系统编程语言、通用编程语言或通用支持。它可以处理以服务器为中心的重型 Web 服务、文本处理问题以及重型分布式应用程序。

为什么要学习 Golang?

熟悉且易于学习。Go属于 C 语言家族,因此它与 Java 和 C++ 等语言拥有许多类似的语法,但 Go 的语法更简洁,因此更易于学习和阅读。与 Python 和 Ruby 类似,它还集成了许多动态编程的特性。

满足开发者需求。Go致力于满足开发者面临的一些常见需求。它加快了软件开发流程,同时又不牺牲效率。Go 旨在通过网络通信、内存管理和速度来支持发展中的市场。

服务端简洁。Go语言让代码的服务器端操作变得简单。Go 标准库提供了标准的 HTTP 协议。

现在我们已经了解了 Go 是什么以及它能带来什么,让我们开始学习基础知识吧。今天,我们将介绍 Go 编程语言的主要概念和核心结构,帮助你入门。和往常一样,我们需要一个更完善的课程来全面讲解 Go 的方方面面。

让我们开始吧。


Go 的基本术语和概念

文件名、关键字、标识符

Go 源代码存储.go文件中。所有文件名均为小写,可以使用_分隔多个单词。与大多数文件名一样,不能使用空格或特殊字符。

Go 中的关键字功能与大多数编程语言类似。这些关键字是保留字,在代码中使用时具有特殊含义。与 Java 或 C++ 不同,Go 的关键字数量要少得多,这使得它更易于使用和学习。这些关键字包括:

替代文本

标识符类似于关键字,但标识符是由程序员创建的。您可以为变量、模板等元素指定名称。与大多数编程语言一样,标识符区分大小写。它们必须以字母或下划线开头,后跟数字。空白标识符_可用于声明或变量赋值。此外,还有 36 个预声明标识符,分别是:

替代文本

基本结构

Go 程序由关键字、运算符、类型、函数和常量组成。代码由语句构成,但不像;许多其他 C 语言那样需要以 结尾。如果一行中有多个语句,则必须用 分隔;

Go 使用与其他语言类似的标点符号,包括. , ; :...

Go 在其代码中使用三个分隔符:( ) [ ]{ }

数据类型和变量

与许多编程语言一样,变量包含不同类型的数据,这些数据定义了一组值或可对这些值进行操作的操作。在 Go 中,您可以使用四种主要数据类型:

  • 基本又称原始):int,,,floatboolstring
  • 结构又称复合材料)struct,,,,,slicemaparraychannel
  • 接口:描述类型的行为

在 Go 中,结构化类型没有固有值,而是有默认值nil

变量是可以在执行过程中更改的值。要声明变量,我们使用关键字var

var identifier type = value
Enter fullscreen mode Exit fullscreen mode

在这个例子中,identifier是变量的名称,type是变量的类型。与其他 C 语言不同,我们type在变量后面写identifier。在 Go 中,当我们声明一个变量时,内存会被初始化。我们还必须使用 运算符为变量赋值=。这个过程称为赋值变量。

还有一种声明变量的简写方式。

   f := "fruit"
    fmt.Println(f)
}
Enter fullscreen mode Exit fullscreen mode

运算符

与许多编程语言一样,运算符是执行逻辑或数学运算的内置符号。Golang 中有三种类型的运算符:算术运算符、逻辑运算符和位运算符。

逻辑运算符与其他编程语言类似。然而,Go 对于可比较的值非常严格。这些运算符包括:

  • 等号运算符==
  • 不等于运算符!=
  • 小于运算符<
  • 大于运算符>
  • 小于等于运算符<=
  • 大于等于运算符>=

位运算符适用于具有相等长度位模式的整数变量。一些位运算符如下:

  • 按位与运算符&
  • 按位或运算符|
  • 按位异或运算符^
  • 位清除操作符&^
  • 按位补码运算符^

算术运算符包括+ / %*

它们执行常见的算术运算,甚至还有一些快捷方式。例如,

b = b + a
Enter fullscreen mode Exit fullscreen mode

可以缩写为

b += a
Enter fullscreen mode Exit fullscreen mode

字符串

字符串实现了操作 UTF-8 编码字符串的函数。它们UTF-8默认进行编码,因此可以包含任何语言的字符。它们被定义在双引号之间“ “,可以包含可变宽度的字符序列,并且是不可变的。

Go 字符串通常比其他语言中的字符串更好,因为它们占用的内存更少,并且由于 UTF-8 标准,您不需要对它们进行解码。

Golang 中有两种字符串字面量:解释型字符串和原始型字符串。解释型字符串用引号括起来,而原始型字符串用反引号括起来。

要声明一个字符串,我们使用string关键字。查看下面的示例来了解如何操作。

package main
import "fmt"

func main() {
  var s string = "Hello, World"
  fmt.Printf(s)
}
Enter fullscreen mode Exit fullscreen mode

输出: Hello, World

你可以循环遍历字符串中的字符来访问单个元素。我们使用for循环,稍后我们会详细讨论。

package main
import "fmt"

func main() {
  var s string = "Hello, World"

  for index, character := range(s){
    fmt.Printf("The character %c is in position %d \n", character, index)
  }
}
Enter fullscreen mode Exit fullscreen mode

输出:
字符 H 位于位置 0
字符 e 位于位置 1
字符 l 位于位置 2 字符
l 位于位置 3 字符
o 位于位置 4 字符
, 位于位置 5 字符位于位置 6
字符
W 位于位置 7
字符 o 位于位置 8

你也可以使用 string 将字节值切片转换为字符串。查看示例了解如何操作。

package main
import "fmt"

func main() {
  myslice := []byte{0x48, 0x65, 0x6C,  0x6C, 0x6f} 
  mystring := string(myslice) 

  fmt.Printf(mystring)
}
Enter fullscreen mode Exit fullscreen mode

输出:你好

时间和日期

在 Golang 中, 包time提供了测量和显示时间的功能。例如,我们可以使用time.Now( )来显示当前时间,并t.Day ( )获取更小的部分。Go 的包有很多有用的功能time,例如 函数Since(t Time),它返回自 以来经过的时间t
您也可以创建自己的时间格式。

t := time.Now()
fmt.Printf("%02d.%02d.%4d\n", t.Day(), t.Month(), t.Year()) // e.g.: 29.10.2019
Enter fullscreen mode Exit fullscreen mode

有关 Gotime包的更多信息,请查看文档

继续学习。

无需浏览视频或文档即可学习 Golang。> Educative 的基于文本的课程易于浏览并具有实时编码环境 - 使学习变得快速而高效。

前进的道路


Go 的中级概念

控制结构

Go 的控制结构与 C 语言类似,但总体上更加简化和灵活。Go 没有doorwhile循环,而是使用灵活的forandswitch循环。

还有新的控制结构,例如类型开关和select。我们不使用括号,并且代码主体使用大括号分隔。让我们深入了解 Go 的控制结构。

if-else:此结构测试条件语句,可以是逻辑值或布尔值。如果语句为true,则执行 { } 之间的语句主体。如果为false,则忽略后面的语句,并执行 之后的语句if。请记住,即使语句主体中只有一个语句,也必须使用括号。

switch-case此结构用于替代if将变量与值进行比较的长语句。此语句可轻松在代码中转移执行流程。

替代文本

switch通常比其他语言更灵活。它采用以下通用形式。

switch var1 {
case val1:
...
case val2:
...
default:
...
}
Enter fullscreen mode Exit fullscreen mode

与构造一样if,aswitch也可以包含初始化语句。

switch initialization; {
case val1:
...
case val2:
...
default:
...
}
Enter fullscreen mode Exit fullscreen mode

select这个语句意味着我们可以等待多个通道操作,我们稍后会详细讨论。

for-range在 Go 中,此语句允许我们迭代一个表达式,该表达式的值可以是数组、切片、映射、字符串或通道。基本语法如下。

for index, value := range mydatastructure {
        fmt.Println(value)
    }
Enter fullscreen mode Exit fullscreen mode
  • index:我们想要访问的值的索引。
  • value:每次迭代的值。
  • mydatastructure:保存我们在循环中访问其值的数据结构。

请记住,此示例仅作概括。要了解更多具体案例,请点击此处for-range查看 EdPresso循环播放的截图。

功能

函数是 Golang 的基本构建块,因为它与函数式语言共享许多特性。正如我之前提到的,函数是数据,因为它们具有值和类型。一个 Go 程序由多个函数组成。最好从main( )函数开始,然后按调用顺序(即逻辑顺序)编写它们。

函数将问题分解成更小的任务,使我们能够重用代码。Go 中有三种类型的函数。它们都会在执行完其之前的最后一个语句}或执行完 return 语句时结束。

  • 使用标识符的普通函数
  • 匿名函数或 lambda 函数
  • 方法

我们使用这种语法编写函数,并使用这种通用格式调用它们。

func g() { // VALID
 ...
}
Enter fullscreen mode Exit fullscreen mode

我们用这种通用格式来称呼它们。

pack1.Function(arg1,arg2,...,argn)
Enter fullscreen mode Exit fullscreen mode

function是一个函数pack1arg1是参数。当我们调用一个函数时,它会复制参数,并将其传递给被调用的函数。

让我们看一个 Go 函数的示例来了解它的实际用法。在这里,我们将深入研究printf( )Golang 中的这个函数。该print函数允许您打印格式化的数据。它接受一个模板字符串,其中包含我们将要格式化的文本,以及一些用于指示fmt函数如何格式化的注解动词。

fmt.printf("Sample template string %s",Object arg(s))
Enter fullscreen mode Exit fullscreen mode

转换字符告诉 Golang 如何格式化数据类型。一些常见的说明符包括:

  • v – 以默认格式格式化值
  • d – 格式化十进制整数
  • g – 格式化浮点数
  • b – 格式化二进制数字

假设我们想要打印一个字符串。%s对话字符可以在模板字符串中使用,以打印字符串值。请看下面的代码。
还有很多其他情况可以使用打印函数。想了解更多,请查看 EdPresso 上关于Golang 打印函数的截图。

package main
import "fmt"

func main() {
  var mystring = "Hello world"
  fmt.Printf("The string is %s", mystring)
}
Enter fullscreen mode Exit fullscreen mode

输出:字符串是 Hello World

地图

映射 (Map),在其他编程语言中也称为哈希 (Hash) 或字典 (Dict),是 Go 语言中的内置数据类型。其名称解释了它们的用途:映射将键映射到值。可以将映射视为一种存储键值对的方式。

替代文本

你可以使用这些方法根据键快速查找、检索或删除数据。
我们使用以下语法声明一个映射

var m map[KeyType]ValueType
Enter fullscreen mode Exit fullscreen mode
  • m是地图变量的名称
  • KeyType是映射中键的可选数据类型。这也可以在初始化时声明。
  • ValueType是键值对中值的数据类型。

映射的长度在声明时无需确定,因此可以动态增长。未初始化映射的值为nil
让我们看一个 Golang 中映射的具体示例,了解它们是如何创建的:

package main
import "fmt"

func main() {
  var mapLit map[string]int   // making map
  var mapAssigned map[string]int
  mapLit = map[string]int{"one": 1, "two": 2}   // adding key-value pair
  mapCreated := make(map[string]float32)        // making map with make()
  mapAssigned = mapLit
  mapCreated["key1"] = 4.5      // creating key-value pair for map
  mapCreated["key2"] = 3.14159
  mapAssigned["two"] = 3        // changing value of already existing key
  fmt.Printf("Map literal at \"one\" is: %d\n", mapLit["one"])
  fmt.Printf("Map created at \"key2\" is: %f\n", mapCreated["key2"])
  fmt.Printf("Map assigned at \"two\" is: %d\n", mapLit["two"])
  fmt.Printf("Map literal at \"ten\" is: %d\n", mapLit["ten"])
}
Enter fullscreen mode Exit fullscreen mode

输出:
“one” 处的映射文字为:1
在“key2”处创建的映射为:3.141590
在“two”处分配的映射为:3
在“ten”处的映射文字为:0

数组和切片

Go 中的数组与 Python 类似,但由于数组不够灵活且大小固定,在 Go 代码中并不常见。相比之下,切片更为常见,功能也更加强大。Go 中的切片基于数组构建,因为它是 Go 数组类型的抽象。

要声明数组,我们使用以下语法:

var identifier [len]type
Enter fullscreen mode Exit fullscreen mode

数组的长度是其类型的一部分,因此其大小是固定的。例如,[5]int表示一个包含五个整数的数组。切片使我们能够克服数组的一些挑战,并在不占用额外内存的情况下处理类型数据序列。

切片是对数组中连续部分的引用,该部分称为底层数组。切片的大小是动态且灵活的。当我们指定两个索引(用冒号分隔)时,就形成了一个切片。我们使用类型规范[ ]T。 T 是切片中元素的类型。我们使用以下语法声明一个切片:

letters := []string{"a", "b", "c", "d"}
Enter fullscreen mode Exit fullscreen mode

要声明带有切片的变量的类型,我们使用[ ]切片的元素类型。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var intSlice []int
    var strSlice []string

    fmt.Println(reflect.ValueOf(intSlice).Kind())
    fmt.Println(reflect.ValueOf(strSlice).Kind())
}
Enter fullscreen mode Exit fullscreen mode

与数组不同,切片在执行过程中可以更改。此外,切片自带内置方法append,可以返回包含一个或多个新值的切片。该append方法的语法如下:

slice = append(slice, elem1, elem2, ...)
Enter fullscreen mode Exit fullscreen mode

看看它是怎么做的。

package main
import "fmt"

// Helper function to. print slices
func printSlice(s []int) {
    fmt.Printf("length=%d capacity=%d %v\n", len(s), cap(s), s)
}

func main() {
    var slice []int // Create an empty slice of type int.
    printSlice(slice)

    // Append works on nil slices.
    slice = append(slice, 0)
    printSlice(slice)

    // Slices can be appended to as many times.
    slice = append(slice, 1)
    printSlice(slice)

    // We can add more than one element at a time.
    slice = append(slice, 2, 3, 4)
    printSlice(slice)
}
Enter fullscreen mode Exit fullscreen mode

输出:
长度=0 容量=0 []
长度=1 容量=1 [0]
长度=2 容量=2 [0 1]
长度=5 容量=6 [0 1 2 3 4]

现在我们已经了解了一些 Go 的中级概念,接下来让我们来看看 Golang 带来的一些重要的高级内容。请记住,还有很多内容需要学习。其他一些中级概念包括:

  • 递归函数
  • 高阶函数
  • 结构和方法
  • 接口和反射
  • 以及更多

Go 的高级概念

错误处理

Go 没有异常处理机制。我们使用内置接口类型error。它的零值是nil,所以如果它返回 ,我们就知道没有错误nil。处理错误的最常见方法是将error类型作为函数调用的最后一个返回值返回,以检查nil。让我们看一些代码来了解它是如何实现的。

package main
import "fmt"
import "errors" // Import the errors package.

func divide(x int, y int) (int, error) {
    if y == 0 {
    return -1, errors.New("Cannot divide by 0!")
  }
  return x/y, nil
}

func main() {
  answer, err := divide(5,0)
  if err != nil {
    // Handle the error!
    fmt.Println(err)
  } else {
    // No errors!
    fmt.Println(answer)
  }
}
Enter fullscreen mode Exit fullscreen mode

输出:不能除以 0!

Goroutine

Go 内置了对并发应用程序的支持。并发程序可以同时执行不同的代码片段。构建并发程序的基本模块是goroutinechannel

与 Java 不同,Go 语言内置了对并发的支持,具体包括特定类型(chan)、关键字(goselect)和结构(goroutine)。Go 更强调并发而非并行,因为 Go 程序默认可能并非并行。Go 程序只使用单个核心或处理器,与运行的 goroutine 无关。

替代文本

那么,什么是 goroutine?它们是与其他方法或函数一起运行的方法或函数。它们取决于我们如何调用它们。你可以把它们想象成线程,但它们更简单、更轻量级。

我们使用关键字go来创建一个 goroutine,因此当我们调用带有该前缀的函数或方法时,就会执行一个 goroutine。

如果您想要更详细地介绍 Goroutines,请参阅文章《Go 中的 goroutines 剖析》

你可以使用变量GOMAXPROCS来告诉运行时有多少个 goroutine 可以执行。GOMAXPROCS必须将其设置为大于默认值 1,否则所有 goroutine 将共享同一个线程。我们来看一个例子。

package main
import (
"fmt"
"time"
)

func main() {
  fmt.Println("In main()")
  go longWait()
  go shortWait()
  fmt.Println("About to sleep in main()")
  time.Sleep(10 * 1e9) // sleep works with a Duration in nanoseconds (ns) !
  fmt.Println("At the end of main()")
}

func longWait() {
  fmt.Println("Beginning longWait()")
  time.Sleep(5 * 1e9) // sleep for 5 seconds
  fmt.Println("End of longWait()")
}

func shortWait() {
  fmt.Println("Beginning shortWait()")
  time.Sleep(2 * 1e9) // sleep for 2 seconds
  fmt.Println("End of shortWait()")
}
Enter fullscreen mode Exit fullscreen mode

输出:
在 main() 中
即将在 main() 中睡眠
开始 longWait()
开始 shortWait()
结束 shortWait()
结束 longWait() 结束
在 main() 结束时

这里的程序表示程序所处的执行阶段的部分。函数main( )、、shortWait( )longWait( )作为独立的处理单元启动,然后同时工作。

通道与 Goroutine 一起使用,以实现它们之间的通信。它们是用于传输数据的类型化消息队列。可以将其视为一个可以发送类型化值的管道。这样,我们可以避免 Goroutine 之间共享内存。一个通道只能传输一种数据类型,但我们可以将其设置为任意类型。

替代文本

要声明一个频道,我们使用以下格式

var identifier chan datatype
Enter fullscreen mode Exit fullscreen mode

通道也是引用类型,因此,我们使用make( )函数来分配内存。下面,看看如何声明一个字符串通道及其实例化。

var ch1 chan string
ch1 = make(chan string)
Enter fullscreen mode Exit fullscreen mode

标准库和包

Go 发行版包含 250 多个内置软件包,并且所有系统的 API 均相同。每个软件包都会为您的 Go 代码引入不同的功能。请参阅此处的文档。

让我们介绍一些常见的软件包,看看它能提供什么。

  • os/exec:可以运行外部操作系统命令和程序。
  • syscall:这是低级的外部包,它为底层操作系统的调用提供了原始接口。
  • archive/tar/zip – compress:包含压缩(解压缩)文件的功能。
  • fmt:包含格式化输入输出的功能。
  • io:提供基本的输入输出功能,主要作为操作系统函数的包装器。
  • bufio:环绕 io 以提供缓冲输入输出功能。
  • path/filepath:包含针对所使用的操作系统来操作文件名路径的例程。
  • strconv:将字符串转换为基本数据类型。
  • unicode:Unicode 字符的特殊功能。
  • regexp:用于字符串模式搜索功能。

该工具还可以安装外部第三方 Go 包go get。您需要验证是否已设置 GOPATH 变量,否则,这些包将被下载到$GOPATH/src目录中。点击此处查看

有超过 500 个实用项目可以添加到您的 Go 程序中。在向现有项目引入新功能时,最好合并现有的 Go 库。这需要您了解库的 API,这会限制调用库的方法。了解 API 后,即可调用库的函数并开始使用。

我们来看一下导入外部库的完整代码。

package main
import (
"fmt"
"time"
"github.com/inancgumus/myhttp"
)

func main() {
  mh := myhttp.New(time.Second)
  response, _ := mh.Get("https://jsonip.com/")
  fmt.Println("HTTP status code: ", response.StatusCode)
}
Enter fullscreen mode Exit fullscreen mode

现在我们对 Go 中的一些高级概念有了一定的了解。还有很多内容需要学习,包括:

  • 接口和反射
  • 错误测试
  • 匿名频道关闭
  • 网络、模板和 Web 应用程序
  • 最佳实践和陷阱
  • 以及更多

资源

Golang 是一门激动人心的语言,它能够加速开发速度并满足您的实际需求。幸运的是,这里有数十个实用的资源可供您学习、练习 Go 语言并与世界分享。快来看看下面的资源,开启您的 Go 之旅吧!

课程

文档和指南

向其他开发人员学习

鏂囩珷鏉ユ簮锛�https://dev.to/educative/getting-started-with-golang-a-tutorial-for-beginners-34fg
PREV
六边形架构教程:构建可维护的 Web 应用程序
NEXT
破解 40 道机器学习面试问题