既然我们要学习这门语言,那么就请我给大家介绍一下什么是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 int= 20 /* 声明实际变量 */
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 结构体
结构体定义需要使用 type 和 struct 语句。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的了解程度还很低,接下来会继续加油的,我将持续发布新的学习笔记。