Go 语言入门指南:基础语法和常用特性解析| 青训营

115 阅读8分钟

既然我们要学习这门语言,那么就请我给大家介绍一下什么是Go语言吧!

一、Go(Golang)的介绍

1.1 Go语言的由来

Go语言(又称Golang)是由Google开发的一种编程语言。它是一种静态类型、编译型语言,旨在提供高效的代码执行速度和简洁的语法。Go语言的设计原则强调了代码的简洁性、可读性和性能。它采用了垃圾回收机制,具有内置并发支持,并提供了丰富的标准库。

1.2 Go语言的特性

  • 高性能、高并发:Go语言使用轻量级的Goroutine来实现并发,使得编写并发程序更加简单。

  • 简洁的语法:Go语言的语法简洁明了,易于学习和阅读,代码可读性较高。

  • 丰富的标准库、完善的工具链

  • 强类型、静态链接:Go语言是静态类型的编程语言,可以提前发现类型错误,并避免一些常见的错误。

  • 快速编译:Go语言的编译速度非常快,可以快速生成可执行文件。

  • 内存管理:Go语言具有自动垃圾回收机制,可以自动管理内存,减轻了程序员的负担。

1.3 使用Go语言的公司

Go语言被广泛应用于构建高性能、可靠、并发的软件,特别适用于网络编程和分布式系统开发。许多知名的项目和公司都在使用Go语言开发各种类型的应用程序,例如字节跳动、谷歌、腾讯、脸书、美团等等。

刚才我们大概了解了一下什么是Go语言,现在就由我来带大家学习一下Go语言的基础语法吧!本文是本人第一次对编程语言入门方面的创作,基于青训营的课程学习和各种资料的总结,若有不足还请各位掘友斧正。

二、Go语言的基础语法

2.1 Hello World

让我们先从Hello World开始

package main  
  
import (  
"fmt"  
)  --这里导入了标准库里面的fmt包,这个包主要是用来往屏幕输入输出字符串、格式化字符串
  
func main() {  
fmt.Println("hello world")  --形式基本和Java一样
}

第一行代码 package main 定义了包名,这里需要注意的是package不是传统意义上的的package,在Java中package用来存放所有的java文件,即多个文件是在同一个包中。你必须指明这个文件属于哪个包,每个 Go 应用程序都包含一个名为 main 的包。

2.2 Go 语言数据类型

  • 布尔类型

  • 数字类型

  • 字符串类型

  • 派生类型

基本上都是常识,我们学其他语言时都学过。

2.3 Go语言变量

变量可以通过变量名访问。

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

声明变量的一般形式是使用 var 关键字:

var identifier type
var identifier1, identifier2 type
//当然我们可以同时声明多个变量

我们也可以不用var如:

v_name := value
//但是如果变量已经使用 var 声明过了,再使用 := 声明变量,就产生编译错误

2.4 Go语言函数

使用关键字 func 定义函数。

函数的参数和返回值可以指定类型。和Java基本一样,只不过数据类型放在了后面,相同数据类型可以只写一个。

func add(a, b int) int {
    return a + b
}

2.5 Go语言条件语句:

  • 使用 if 进行条件判断。
  • 使用 else 处理分支情况。
  • 使用 switch 进行多条件判断。

2.6 Go语言循环语句:

  • 使用 for 进行循环操作。
  • 可以使用 break 和 continue 控制循环流程。
  age := 18
    if age >= 18 {
        fmt.Println("成年")
    } else {
        fmt.Println("未成年")
    }

    for i := 0; i < 5; i++ {
        fmt.Println(i)
    } 

    switch day {
        case "Monday":
            fmt.Println("星期一")
        case "Tuesday":
            fmt.Println("星期二")
        default:
            fmt.Println("其他")
    }

是不是熟悉的感觉都回来了呢?

2.7 数组、指针、结构体

2.7.1 数组

和Java基本是一样的,过于简单。

var numbers [5]int
//还可以使用初始化列表来初始化数组的元素:
var numbers = [5]int{1, 2, 3, 4, 5}
//当然还能偷懒
numbers := [5]int{1, 2, 3, 4, 5}

2.7.2 指针

Go 语言的取地址符是 &,取值则为*

指针使用流程:

  • 定义指针变量。
  • 为指针变量赋值。
  • 访问指针变量中指向地址的值。

在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。

实例:

package main  
  
import "fmt"  
  
func main() {  
   var a int20   /* 声明实际变量 */  
   var ip *int        /* 声明指针变量 */  
  
   ip = &a  /* 指针变量的存储地址 */  
  
   fmt.Printf("a 变量的地址是: %x\n", &a  )  
  
   /* 指针变量的存储地址 */  
   fmt.Printf("ip 变量储存的指针地址: %x\n", ip )  
  
   /* 使用指针访问值 */  
   fmt.Printf("*ip 变量的值: %d\n", *ip )  
}  

以上实例执行输出结果为:

a 变量的地址是: 20818a220
ip 变量储存的指针地址: 20818a220
*ip 变量的值: 20

2.7.3 结构体

结构体定义需要使用 typestruct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:

type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}

一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:

variable_name := structure_variable_type {value1, value2...valuen}
或
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}

2.8 切片、范围、集合

2.8.1 切片

切片

切片是一个可变长度的数组,这就是java中的向量,简单。

var identifier []type
var slice1 []type = make([]type, len)
//也可以简写为
slice1 := make([]type, len)
//初始化
s :=[] int {1,2,3 } 
s := arr[:] 
s := arr[startIndex:endIndex] 

2.8.2 范围

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。

for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:

for key, value := range oldMap {
    newMap[key] = value
}
//key 和 value 是可以省略的
for key := range oldMap

2.8.3 集合

Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,遍历 Map 时返回的键值对的顺序是不确定的。

在获取 Map 的值时,如果键不存在,返回该类型的零值,例如 int 类型的零值是 0,string 类型的零值是 ""。

可以使用内建函数 make 或使用 map 关键字来定义 Map:

/* 使用 make 函数 */
map_variable := make(map[KeyType]ValueType, initialCapacity)

其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。Map 的容量是指 Map 中可以保存的键值对的数量,当 Map 中的键值对数量达到容量时,Map 会自动扩容。如果不指定 initialCapacity,Go 语言会根据实际情况选择一个合适的值。

m := make(map[string]int)  
  
// 创建一个初始容量为 10 的 Map  
m := make(map[string]int, 10)

三、常用特性解析

3.1 并发

Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。

goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。

goroutine 语法格式:

go 函数名( 参数列表 )
//例如:
go f(x, y, z)

3.2 接口

与Java中基本一样

package main

import "fmt"

type Shape interface {
    area() float64
}

type Rectangle struct {
    width  float64
    height float64
}

func (r Rectangle) area() float64 {
    return r.width * r.height
}

type Circle struct {
    radius float64
}

func (c Circle) area() float64 {
    return 3.14 * c.radius * c.radius
}

func main() {
    var s Shape

    s = Rectangle{width: 10, height: 5}
    fmt.Printf("矩形面积: %f\n", s.area())

    s = Circle{radius: 3}
    fmt.Printf("圆形面积: %f\n", s.area())
}

以上实例中,我们定义了一个 Shape 接口,它定义了一个方法 area(),该方法返回一个 float64 类型的面积值。然后,我们定义了两个结构体 Rectangle 和 Circle,它们分别实现了 Shape 接口的 area() 方法。在 main() 函数中,我们首先定义了一个 Shape 类型的变量 s,然后分别将 Rectangle 和 Circle 类型的实例赋值给它,并通过 area() 方法计算它们的面积并打印出来。

3.3 错误处理

Go 语言通过内置的错误接口提供了非常简单的错误处理机制。

error 类型是一个接口类型,这是它的定义:

type error interface {
    Error() string
}

我们可以在编码中通过实现 error 接口类型来生成错误信息。

函数通常在最后的返回值中返回错误信息。使用 errors.New 可返回一个错误信息:

func Sqrt(f float64) (float64, error) {
    if f < 0 {
        return 0, errors.New("math: square root of negative number")
    }
    // 实现
}

四、个人思考及总结、

千里之行,始于足下。这也是鄙人第一次写这种长篇学习笔记,感谢这次青训营给我的机会,我本人很少花时间写作,大部分时间还是在运用上,用久了还可能会遗忘,这样写下来,就相当于有了自己专属的文档,毕竟自己的东西还是自己熟悉,马上就能从遗忘中恢复。本人之前只学过Java,所以学习Go语言我是从它们两者的异同入手的,所以有的地方一笔带过,还请各位谅解,目前本人对Go的了解程度还很低,接下来会继续加油的,我将持续发布新的学习笔记。