Go入门篇:(二)基础知识之结构,包,变量初探

简介: Go入门篇:(二)基础知识之结构,包,变量初探

一、目录结构

在Go语言中,程序的代码文件需按照特定的目录结构进行组织。在早期版本的Go中,常见的目录结构如下所示:

- bin:用于存放可执行文件
- pkg:用于存放编译后生成的包文件
- src:用于存放源代码文件
    - main.go:主程序入口文件
    - package1:自定义包1
    - package2:自定义包2

在Go 1.11版本之前,要求项目必须按照bin、pkg、src的目录结构进行组织,src目录通常包含多个项目,每个项目都是一个独立的代码仓库。这是因为在早期的Go版本中,代码必须放在GOPATH环境变量指定的目录下,而src目录就是其中的一部分。

由于早期的Go版本中需要使用GOPATH作为代码仓库的根目录,因此往往会在src目录下创建多个独立的项目目录。每个项目目录中存放着这个项目的所有源代码文件以及依赖的包。

例如,假设在Go 1.10版本中,我们有两个项目,一个是名为project1的项目,另一个是名为project2的项目。在src目录下,就会有两个独立的项目目录,分别是project1和project2。

示例目录结构:

- bin/
    - myapp
- pkg/
    - utils.a
- src/
    - project1/
        - main.go
        - package1/
            - package1.go
    - project2/
        - main.go
        - package2/
            - package2.go

多个项目在src下。这是go的历史,需要了解,1.11版本之后可以不按这个来,我个人觉得1.11之前这种目录结构就比较别扭。尽管如此,在官方仍然建议使用类似于早期目录结构的方式来组织代码,即将可执行文件放在bin目录下,编译后生成的包文件放在pkg目录下,源代码文件放在src目录下。这种目录结构的好处是可以与早期的代码兼容,并且使项目的结构更加清晰、易于阅读和维护。

在Go 1.11版本之后,引入了模块化开发的概念,不再强制要求使用特定的目录结构。这意味着我们可以在任意的目录中创建Go模块,而不一定需要将项目代码放在GOPATH环境变量指定的目录下。这样能够使项目的代码组织更加灵活和便捷。我们可以将go.mod所在的目录作为项目的根目录进行开发。go.mod文件定义了Go模块,标识了项目的名称以及依赖的包。在项目的根目录下,通常会包含一个main包和一个main函数。main包是一个特殊的包,它包含了程序的入口点,也就是main函数。在运行一个Go程序时,会先执行main函数。

以下是一个1.11版本后示例的项目结构:

- myproject/
    - go.mod
    - main.go
    - package1/
        - package1.go

在上述示例中,myproject是项目的根目录,它包含了一个go.mod文件和几个源代码文件。main.go是主程序的入口文件,它位于根目录下。这个文件中的main函数定义了程序的入口逻辑。package1是一个自定义包,它位于根目录下的package1子目录中。在该子目录中可以有多个源代码文件,用于组织package1包的代码。

需要注意的是,在Go语言中,如果一个项目是可执行程序,那么它必须包含一个main包和一个main函数。这是因为在运行该程序时,Go编译器将首先执行main函数。如果一个项目是库,那么它不需要包含main包和main函数,而是可以定义其他类型的包和函数来实现特定的功能。

综上所述,在Go 1.11及以后的版本中,建议将go.mod所在的目录作为项目的根目录进行开发,并在根目录下包含一个main包和一个main函数,定义程序的入口逻辑。

这个跟Java就比较像了,我喜欢这种目录结构,更加灵活和便捷。(新手推荐用这种目录结构)

go.mod

可以将的go.mod文件视为类似于Java中Maven的pom.xml文件的功能。go.mod文件是用于定义Go模块的文件,其中包含了项目的元数据和依赖信息。它类似于pom.xml文件中定义的项目元数据和依赖项。类似于pom.xml文件中的groupIdartifactIdversion等标签,go.mod文件中也有类似的字段,如modulerequireexclude等。

  • module字段指定了项目的模块名称,相当于Maven中的groupId
  • require字段用于指定项目的依赖项及其版本,相当于Maven中的dependencies
  • exclude字段用于排除特定的依赖项,相当于Maven中的exclusions

通过go mod init命令可以创建并初始化go.mod文件,类似于Maven中的mvn init命令可以创建并初始化pom.xml文件。

在项目开发过程中,我们可以使用go get命令来添加或更新依赖项,类似于Maven中的mvn installmvn dependency:addmvn dependency:upgrade等命令。

因此,可以将Go语言中的go.mod文件视为类似于Java中Maven的pom.xml文件的功能,用于管理项目的元数据和依赖项。它们都提供了便于管理项目的依赖关系以及版本控制的方式。

二、包

包是Go语言中用于组织和管理代码的基本单位。通过使用包,我们可以将功能相似的代码进行组织,并能方便地复用。在Go语言中,包的声明和使用如下所示:

  • 声明包:在代码文件的开头使用package关键字声明当前文件所属的包。例如,一个名为package1的包可以这样声明:
package package1
  • 引入包:在使用其他包的代码文件中,使用import关键字引入对应的包。例如,引入名为package1的包可以使用以下代码:
import "package1"

通过声明和引入包,我们可以更好地组织和管理代码,提高代码的可复用性和可维护性。

如果一个项目是可执行程序,那么它必须包含一个main包和一个main函数。

Go Web开发较通用的脚手架模板目录结构示例:

三、变量

3.1 为什么需要变量

3.1.1 一个程序就是一个世界

当我们说"一个程序就是一个世界"时,我们是在比喻一个程序所创造的运行环境就像是一个独立的世界一样。这个世界中有自己的规则、逻辑和元素,就像现实世界一样。想象一下,当我们编写一个程序时,我们实际上是在创造一个虚拟的世界。在这个世界里,我们可以定义各种变量,就像在现实世界中有各种不同的事物和物品一样。这些变量可以存储数据,代表不同的属性或状态。在这个程序的世界中,我们可以定义函数,就像在现实世界中有各种不同的行为和动作一样。这些函数可以执行特定的任务,操作变量的值,实现各种功能和逻辑。这个程序的世界也有自己的规则和逻辑。我们可以使用条件语句和循环结构来控制程序的流程,就像在现实世界中有各种规则和限制一样。我们可以通过编写算法来解决问题,就像在现实世界中需要思考和解决各种难题一样。总之,一个程序就像是一个独立的世界,它有自己的元素、规则和逻辑。通过编写程序,我们可以创造出这个世界,并在其中实现各种功能和逻辑。这个世界的存在完全依赖于程序的运行,就像现实世界的存在依赖于自然规律一样。

3.1.2 变量是程序的基本组成单位

变量是程序中存储和操作数据的基本单位。无论使用哪种高级编程语言,变量都是程序的基本组成单位。变量可以用来存储和表示数据,在程序的世界中扮演着各种不同的角色。通过使用变量,程序可以在运行时动态地存储和操作数据,从而实现各种功能和逻辑。因此,变量与程序的关系在于,它们是程序中用来存储和操作数据的重要工具。程序通过使用变量来创建和维护自己的虚拟世界,实现各种功能和逻辑。

示例:

package main
import "fmt"
func main() {
 // 声明一个整数类型的变量
 var num1 int
 num1 = 10
 fmt.Println(num1) // 输出:10
 // 声明并初始化一个字符串类型的变量
 var str string = "Hello, World!"
 fmt.Println(str) // 输出:Hello, World!
}

如上图中num1和str都是变量

3.2 变量的介绍

变量是Go语言中的基本概念之一,用于存储和表示数据。在Go语言中,变量需要先声明后使用,并且每个变量都有一个特定的类型。变量名就像是门牌号一样,通过它我们可以访问到变量所存储的值。就像通过房间的门牌号可以找到对应的房间一样,通过变量名可以找到对应的变量值。变量名在程序中起到了标识和引用变量的作用,它们允许我们在程序中使用和操作变量的值。通过变量名,我们可以读取和修改变量的值,进行各种计算和逻辑操作。

变量的声明方式

在Go语言中,有多种方式可以声明变量,包括简单声明、类型推断声明、多变量声明、匿名变量声明和短变量声明。下面分别详细介绍这些变量声明方式的示例。

1. 简单声明: 简单声明是一种最基本的变量声明方式,可以单独声明一个或多个变量,每个变量都指定了类型。

package main
import "fmt"
func main() {
 var name string
 var age int
 name = "John"
 age = 30
 fmt.Println("Name:", name)
 fmt.Println("Age:", age)
}

2. 类型推断声明: 类型推断声明是一种简化的变量声明方式,不需要显式指定变量的类型,而是根据变量的初始值来推断其类型。

package main
import "fmt"
func main() {
 var name = "John"
 var age = 30
 fmt.Println("Name:", name)
 fmt.Println("Age:", age)
}

3. 短变量声明: 短变量声明是一种简单且常用的变量声明方式,省略了var, 可以在函数内部使用,通过 := 操作符进行声明和赋值。

package main
import "fmt"
func main() {
 name := "John"
 age := 30
 fmt.Println("Name:", name)
 fmt.Println("Age:", age)
}

这是在开发中用的最多的方式。

4. 多变量声明: 多变量声明是一种同时声明多个变量的方式,可以在一行代码中声明多个变量,并可以给它们赋初值。

package main
import "fmt"
func main() {
 var (
  name string = "John"
  age  int    = 30
 )
 fmt.Println("Name:", name)
 fmt.Println("Age:", age)
}

5. 匿名变量声明: 匿名变量是一种特殊的变量,用 _ 表示,通常用于忽略某个值或占位。

package main
import "fmt"
func getData() (int, string) {
 return 42, "Hello"
}
func main() {
 _, message := getData()
 fmt.Println(message)
}

通过上述示例,我们详细介绍了Go语言中不同的变量声明方式,包括简单声明、类型推断声明、多变量声明、匿名变量声明和短变量声明。每个示例都展示了相应的代码,并说明了该方式的特点和用法。这些示例代码是可运行的,并可以直接在Go环境中执行。

四、总结

Go语言中的目录结构、包和变量是学习和使用Go语言的基础知识。通过了解和掌握这些基础知识,我们可以更好地理解和使用Go语言进行开发。在接下来的学习过程中,我们将深入探索更多的Go语言特性和功能。

相关文章
初识go变量,使用var和:=来声明变量,声明变量的三种方式
这篇文章介绍了Go语言中使用`var`和`:=`声明变量的三种不同方式,包括声明单个或多个变量、通过值确定数据类型以及在函数体内使用`:=`声明局部变量。
初识go变量,使用var和:=来声明变量,声明变量的三种方式
|
12天前
|
程序员 Go
go语言中的控制结构
【11月更文挑战第3天】
88 58
|
12天前
|
存储 编译器 Go
go语言中的变量、常量、数据类型
【11月更文挑战第3天】
29 9
|
13天前
|
存储 设计模式 安全
Go语言中的并发编程:从入门到精通###
本文深入探讨了Go语言中并发编程的核心概念与实践技巧,旨在帮助读者从理论到实战全面掌握Go的并发机制。不同于传统的技术文章摘要,本部分将通过一系列生动的案例和代码示例,直观展示Go语言如何优雅地处理并发任务,提升程序性能与响应速度。无论你是Go语言初学者还是有一定经验的开发者,都能在本文中找到实用的知识与灵感。 ###
|
14天前
|
编译器 Go 开发者
go语言中导入相关包
【11月更文挑战第1天】
27 3
|
18天前
|
Serverless Go
Go语言中的并发编程:从入门到精通
本文将深入探讨Go语言中并发编程的核心概念和实践,包括goroutine、channel以及sync包等。通过实例演示如何利用这些工具实现高效的并发处理,同时避免常见的陷阱和错误。
|
1月前
|
安全 Go 开发者
破译Go语言中的并发模式:从入门到精通
在这篇技术性文章中,我们将跳过常规的摘要模式,直接带你进入Go语言的并发世界。你将不会看到枯燥的介绍,而是一段代码的旅程,从Go的并发基础构建块(goroutine和channel)开始,到高级模式的实践应用,我们共同探索如何高效地使用Go来处理并发任务。准备好,让Go带你飞。
|
1月前
|
存储 安全 Go
Go语言切片:从入门到精通的深度探索###
本文深入浅出地剖析了Go语言中切片(Slice)这一核心概念,从其定义、内部结构、基本操作到高级特性与最佳实践,为读者提供了一个全面而深入的理解。通过对比数组,揭示切片的灵活性与高效性,并探讨其在并发编程中的应用优势。本文旨在帮助开发者更好地掌握切片,提升Go语言编程技能。 ###
|
1月前
|
存储 Go 数据库
Go语言Context包源码学习
【10月更文挑战第21天】Go 语言中的 `context` 包用于在函数调用链中传递请求上下文信息,支持请求的取消、超时和截止时间管理。其核心接口 `Context` 定义了 `Deadline`、`Done`、`Err` 和 `Value` 方法,分别用于处理截止时间、取消信号、错误信息和键值对数据。包内提供了 `emptyCtx`、`cancelCtx`、`timerCtx` 和 `valueCtx` 四种实现类型,满足不同场景需求。示例代码展示了如何使用带有超时功能的上下文进行任务管理和取消。
|
10天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
30 2
下一篇
无影云桌面