Go语言入门指南:基础概念与实用技巧

426 阅读6分钟

1.如何快速开始Go学习

对于Go的初学者来说,很多人推荐是先看Go语言圣经,我之前也看了一遍,有点难懂,有些知识点要看好几遍才明白过来。

还有一些推荐的不错的书籍,像Go语言高级实战、Go并发编程等等,都需要一些Go基础才能更好的消化吸收,所以走了一些弯路之后,我决定从Go指南开始,先熟悉基础的语法特性,打好基础之后再进行下一阶段的学习。

因为我对Java比较熟悉,所以很多的知识点我会先类比Java中的概念,对比相似与差异的部分,以及Java所不具备的特性,达到一个快速吸收的过程。

2.了解语言特性

从Hello World开始

遵从语言学习惯例,从Hello World开始走进Go的大门

  package main
  
  import "fmt"
  
  func main()  {
    fmt.Println("Hello World!")
  }

可以简单的看出一些不同,比如

  • 上面的package,import
  • 语句结束没有分号

每个Go程序都是由包构成的,比如上个例子中的程序就是从main包开始运行的

math

math包下提供一些常见的数学函数,比如绝对值,平方根,四舍五入等。类比Java中的Math工具类


package main

import (
  "fmt"
  "math"
)

func main()  {

  fmt.Printf("you have %g number",math.Sqrt(5))
}

分组导入

分组导入也就是上个例子中import的圆括号,也可以单独导入,比如:

import "fmt"

import "math"

推荐使用分组导入。

fmt

fmt实现了格式化的I/O函数,目前用到的有Printf和Println两个函数,Printf支持格式化打印,Println支持换行打印,否则需要加换行符\n。

常见格式符

%g:浮点数和负数的组成部分

%v:打印相应值的默认形式 普通占位符

%T:打印相应值的Go语法表示 普通占位符

先说几个常见的,具体的Demo后期再写一篇详细版本的。

参考自 fmt格式占位符

导出名

在Go中,如果一个名字是以大写字母开头的,那就是已导出的。当我们导入一个包的时候只能引用已导出的名字,所有未导出的在该包外均无法访问

比如调math的Pi可以正常引用,但是改成pi就不行。

函数

函数可以不传入参数或者传入多个参数。

类型在变量名之后,这点与Java正好相反。

package main

import "fmt"

func multi(x int, y int) int {
return x * y
}

func main() {
fmt.Println(multi(8, 5))

// print
40
}

函数之返回值

从上个例子中也可发现,函数返回值的写法也与Java不同;

Java的返回值是在参数之前。

函数形参

当多个形参类型相同时,除了最后一个行参的类型需要保留,其余都可以省略,比如上例中

(x int,y int)

可改为

(x,y int)

函数多值返回

在单值返回的案例中,返回值在参数后面,不需要括号包裹。比如上一个代码中的(x int,y int) int。

Go的函数还支持多值返回,返回值在参数后面,需要用括号包裹,需要接受返回值的类型,比如(x,y string) (string,string)

package main

func main() {
  a,b := swap("Hello","World")
  println(a,b)
}

func swap(x,y string) (string,string) {
  return y,x
}

函数命名返回值

函数中执行没有参数的return语句,也就是不显式的指定返回元素,而在接收返回值处命名。

对比下面的代码示例中与上面示例中返回值处定义的不同。


package main

import "fmt"

func cut(sum int) (x, y int) {
	x = sum * 3 / 9
	y = sum - x
	return
}

func main() {
	fmt.Println(cut(23))
}

var

var可用于声明一个变量,或者变量列表。和函数的参数一样,类型在后面。

var可以出现在包级别函数级别

类比Java中是全局变量局部变量吧。


package main

import "fmt"

var c, c++ bool

func main() {
  var i int
  fmt.Println(i, c, c++)
}

短变量声明

语法规则

  • 简洁赋值语句 :=
  • 只能在函数体内使用
  • 支持变量推导

如下

func main() {

   user := "jac"
   fmt.Println(user)

}

变量的初始化

变量初始化的方法可以在声明变量时赋值,这点与Java区别不大。

也可以省略变量类型,根据值会推导出类型

  // 初始化赋值
  var x,y int = 2,3
  
  // 推导类型 推导出c是bool类型
  var c = true

基本类型

Go的基本类型有

  • string 字符串 (注意小写)
  • bool 布尔
  • int 还有 int8 int16 int32 int64
  • uint 还有 uint8 uint16 uint32 uint64 uintptr
  • byte (uint8别名)
  • rune (int32别名,表示一个Unicode码点)
  • float32 float64
  • complex64 complex128

int大家族,相比于Java的int,Go语言的int有各种类型。

Go语言int类型大小与操作系统位数有关。32位操作系统占4个字节,64位操作系统占8个字节。

int 8字节

int8 1字节 盲猜是8个比特位=1个字节 也就是对应了byte类型

int16 2字节

int32 4个字节 对应一个码点 rune类型

int64 8个字节

零值

没有初始化进行赋值的变量会赋予零值,根据变量类型不同零值不同,这部分与Java很相似,如

  • 数值类型为0
  • 布尔类型为false
  • 字符串为""

类型转换

表达式:T(v) 意味着将v的值转换为类型T

可以用 T t = T(v) 来理解,对于Go的话有类型推导,很多类型声明可以省略。


// 完整写法
var i int = 33
var f float64 = float64(i)

// 简洁写法
i := 33
f := float64(i)

类型推导

在声明变量但是没有指定类型时,可以根据表达式右边的值推导出变量的类型,支持

  • var声明变量
  • 短变量声明

但是当右边包含未指明类型的数值常量时,会根据常量的精度进行推导。


func main() {
// 尝试修改v的值,比如3.14再试试打印出来类型
    v := 42 
    fmt.Printf("v is of type %T\n", v)
}    

常量

语法规则:

  • 用const关键字修饰
  • 可以是字符、字符串、布尔值和数值
  • 不能用短变量声明
const Pi = 3.14
const type = "掘金"

数值常量

数值常量是一个高精度的值,一个未指定类型的数值常量由上下文推导而出。

练习直通车

Go指南

本节复习手册

3.总结

今天主要从包、变量与函数三方面来加深对Go程序基本结构的掌握,把涉及到的知识点拆分的也比较细。虽然很基础,但是也需要去不断的练习,加深对知识点的理解。