Go语言结构

Go程序组成部分

  1. 包声明 (Package Declaration) :定义该文件属于哪个包。
  2. 引入包 (Import) :引入该文件需要使用的外部库或包。
  3. 函数 (Functions) :执行特定任务的代码块。
  4. 变量与常量 (Variables & Constants) :存储数据的容器。
  5. 语句与表达式 (Statements & Expressions) :具体的逻辑代码。

我们可以通过一个简单的Go程序实例来分析:

1
2
3
4
5
6
7
8
9
10
11
12
// 1. 包声明:定义包名
// main 包是一个特殊的包,代表这是一个可执行程序,而不是一个库
package main

// 2. 引入包:引入标准库中的 fmt 包(用于格式化输入输出)
import "fmt"

// 3. 函数:main 函数是程序的入口,程序从这里开始执行
func main() {
/* 4. 语句与表达式 */
fmt.Println("Hello, World!")
}

核心结构:

  1. 包声明(Package)

    每个Go文件的第一行非注释代码必须是包声明语句!

    如果包名是main,则编译器会将该包编译为程序,而并非库

    语法:package <name>

  2. 导入包(Import)

    • Go 语言有一个严格的规则:导入但未使用的包会导致编译错误

      语法:import "package_name"

    1
    2
    3
    4
    import (
    "fmt"
    "math"
    )
  3. 函数 (Functions)

    • func用来定义函数

    • main()函数是程序的默认入口点,无参数构造,也无返回值

  4. 注释(Comments)

    • 单行注释:使用 //
    • 多行注释:使用 /* ... */
  5. 标识符与可见性(重要)

    Go 语言通过首字母的大小写来决定变量、函数或常量的访问权限:

    • 首字母大写(如 Println):表示 公有 (Public) ,可以被其他包调用。
    • 首字母小写(如 myVar):表示 私有 (Private) ,仅在当前包内可见。

Go 语言的编码规范(语法特点)

Go 语言在结构上有几个非常鲜明的特征:

  1. 行分隔符(分号)

    在 Go 中,你不需要在每一行语句末尾写分号 ;

    Go 编译器会自动在行尾添加分号。如果你把多个语句写在同一行,才需要用分号隔开(但不推荐这样做)。

  2. 大括号 { } 的位置

    在 Go 中,左大括号 { 必须与关键字(如 funciffor)在同一行。如果换行写左大括号,会导致编译错误。

  3. 强制代码格式化

    Go 官方提供了一个工具 go fmt,它会自动统一所有人的代码风格(如缩进、空格等)。


额外思考:Go是面向对象的变成语言吗?

关于 Go 语言是否是面向对象(OOP)语言,Go 官方文档(FAQ)给出的回答非常经典:

“Yes and no.”(是,也不是。)

Go 拥有面向对象的特性(部分)

  1. 封装 Encapsulation

    在传统的OOP语言中,往往使用类来实现封装(Java中的class关键词)

    在Go中,使用结构体(struct)来实现,同时采用可见性控制来控制访问控制。

    • 大写字母开头:包外可见(对应Java中的public关键词)
    • 小写字母开头:仅包内可见(对应Java中的private关键词)
  2. 多态 Polymorphism & Interfaces

    使用 interface

    同时:Go 的接口实现是隐式的。你不需要显式地写 implements。只要一个类型实现了接口中定义的所有方法,它就自动实现了该接口。这是 Go 处理多态最强大的地方

Go所丢失的面向对象的特征

  1. 类(class)

    在Go中,不存在class类关键词。而结构体struct仅包含数据,通过方法func独立定义通过一定方法与结构体绑定。

  2. 继承

    在Go中,不存在继承关系(类似于Java中的class A extend B或者Python中Class A(B):

  3. 构造方法

    在Go中没有构造方法,通常通过普通函数来模拟构造。

Go的核心哲学:组合 (Composition)

虽然没有继承,但Go通过 结构体嵌套(Embedding) 实现了类似的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Animal struct {
Name string
}

func (a Animal) Eat() { fmt.Println("Eating...") }

type Dog struct {
Animal // 嵌入 Animal 结构体,Dog 自动获得了 Animal 的字段和方法
Breed string
}

// 使用时
d := Dog{}
d.Eat() // 直接调用 Animal 的方法,看起来像继承,其实是组合