前言

这次就要正式进入Go语言的学习之旅了。Go语言系列:Go从哪里来,Go将去哪里?和Go语言系列:如何搭建Go语言开发环境?分别介绍了Go语言的起源、现状和开发环境的搭建。那既然迈出了第一步,就要去闯出一片天地出来。所以,想要入坑Go语言的小伙伴赶紧上车,让我们一起去探寻GO语言的神秘之处吧

这篇文章只是Go语言入门的第2篇文章,所以本文并不会对一些语法使用进行深挖。只会停留在“怎么用”的层面,至于“为什么是这样”,就不会在文章中去过深地赘述。毕竟我也是刚入坑,你硬是要问我为什么,那我也不知道,只有深入了解Go语言之后才会有答案的。

Go语言基本的语法

下面就开始进入Go语言的基本语法学习啦~

一、变量

编程语言中最基本的就是变量,变量是用来存储各种类型数据的抽象概念。Go语言中不同类型的变量,需要先声明才能被使用。

1.1 声明变量

1.1.1 标准格式

Go语言中声明变量以var关键字开头,变量名放中间,变量类型放在最后。如下:

var 变量名 变量类型
复制代码

1.1.2 批量格式

如果觉得每次在多个变量前面都要定义var非常繁琐,可以通过var和括号来批量声明。如下:

var (
    a int
    b string
    c bool
)
复制代码

注意:Go语言中不需要用分号结尾,除非多个语句或声明出现在同一行;字符串必须是双引号,单行注释是//,多行注释是/**/

1.2 初始化与定义变量

变量声明好了,那就可以对其进行初始化。在Go语言中,初始化变量有如下几种方法:

1.2.1 标准格式

var 变量名 变量类型 = 变量值
复制代码

举个例:

var a int = 18 // 初始化一个整数,变量名为a,初始值为18的变量
复制代码

1.2.2 编译器推导类型

编译器推导类型顾名思义就是在没有给变量定义类型时,编译器会自行根据等号右边的变量值来推断变量的类型。如下:

var a = 18
复制代码

1.2.3 短变量声明与初始化

短变量声明其实就是省略var的写法,如下:

a := 18
复制代码

注意: 因为使用了 := , 而不是赋值的 =, 这就限制了等号左边的变量名必须是没有定义过的变量名,否则将会发生编译错误

举个例:

var a int // 声明一个整型a变量
a := 18 // 再次声明与赋值
复制代码

编译的时候就会报错,如下:

no new variables on left side of :=      // :=左边的变量已经被声明了
复制代码

1.3 多变量同时赋值

多变量同时赋值的场景主要来源于需要交换两个变量值的需求,传统的做法就是再定义一个临时变量来做中转;但是在Go语言中就可以利用多重赋值的特性来实现,如下:

var a int = 100
var b int = 200

a, b = b, a
fmt.Println(a, b)
复制代码

运行代码得到如下结果:

200 100
复制代码

1.4 匿名变量

匿名变量就是一个没有名字的变量,使用下划线_来表示。

假设GetName()函数的定义如下,它返回3个值,分别为firstNamelastNamenickName

func GetName() (firstName, lastName, nickName) { 
    return "Kobe", "Bryant", "Mamba" 
} 
复制代码

若只想获得firstName,则函数调用语句可以用如下方式编写:

firstName, _, _ := GetName()
复制代码

注意:匿名变量不占用内存,不分配内存;匿名变量与匿名变量之间也不会因为多次的声明而无法使用。

二、基础数据类型

Go语言中的基础数据类型包含:整型、浮点型、布尔型、字符串、字符等。下面就来挨着介绍这几种基础的数据类型。

2.1 整型

Go语言中,整型分为以下两个大类:

  • 有符号类型,按长度分为:int8int16int32int64
  • 无符号类型,与上对应为:uint8uint16uint32uint64

看了上述的类型,是不是觉得这也太繁琐了点,定义一个整型变量居然如此花里胡哨,那有没有简便的方法呢?有!那就是直接使用intuint,自己根据平台cpu机器字节大小来调整长度。

最后,还有一种无符号的整数类型 uintptr,它没有指定具体的 bit 大小但是足以容纳指针。uintptr类型只有在底层编程时才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。

2.2 浮点型

Go语言中提供了2种精度浮点型float32float64。这2种浮点型数据格式遵循IEEE754浮点数国际标准,该浮点数规范被所有现代的CPU支持。

浮点型Float32:即单精度,存储占用4个字节,也即4*8=32位,其中1位用来符号,8位用来指数,剩下的23位表示尾数。

浮点型Float64:即双精度,存储占用8个字节,也即8*8=64位,其中1位用来符号,11位用来指数,剩下的52位表示尾数。

float32的浮点数最大值约为3.4e38,最小值为1.4e-45float64的浮点数最大值约为1.8e308,最小值为4.9e-324

一个float32类型的浮点数可以提供大约6个十进制数的精度,而float64则可以提供约15个十进制数的精度;通常应该优先使用float64类型,因为float32类型的累计计算误差很容易扩散,并且float32能精确表示的正整数并不是很大(注意:因为float32的有效bit位只有23个,其它的bit位用于指数和符号;当整数大于23bit能表达的范围时,float32的表示将出现误差)。

浮点数常量的表示:

-小数点前数字可省略:.234

-小数点后数字可省略:23.

-科学计数法:2e234E23。(非常大或者非常小的值建议使用此方式)

注意:NaN,表示科学上无意义的运算结果,如0/0sqrt(-1),通过match.IsNaN()函数判断一个变量或表达式的值是否为NaN

最后,Go语言中通过Printf函数打印浮点数时,可以使用**%f**来控制保留几位小数,如下:

package main 
import ( 
    "fmt" 
    "math" 
) 

func main() { 
    // 打印默认宽度和精度的圆周率, \n 为换行符 
    fmt.Printf("%f\n", math.Pi) 
    
    // 打印默认宽度, 精度(小数点后的位数)为2的圆周率 
    fmt.Printf("%.2f\n", math.Pi) 
}
复制代码

运行结果如下:

3.141593 
3.14
复制代码

2.3 布尔型

Go语言中,以关键字bool来声明布尔类型。布尔类型只有true 和 false两种值。

if和 for语句的条件部分都是布尔类型的值,并且==和 <等比较操作也会产生布尔型的值。一元操作符!对应逻辑非操作,因此!true的值为false,一般会采用简洁的布尔表达式,就像用x来表示x==true

布尔值可以和&&(AND)||(OR)操作符结合,并且有短路行为:如果运算符左边值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值。

&&的优先级比||高(PS:&&对应逻辑乘法,||对应逻辑加法,乘法比加法优先级要高),下面形式的布尔表达式是不需要加小括弧的,如下:

if 'a' <= c && c <= 'z' || 
    'A' <= c && c <= 'Z' { 
    // ...do something... 
}
复制代码

注意:Go语言中布尔类型无法参与数值运算,也无法与其他类型进行转换 !

package main 
import "fmt" 

func main() { 
    var a bool 
    fmt.Print(int(a) * 2) // 将变量 a 强制转换为 int 类型,并乘以 2 
}
复制代码

运行上面的代码,会发生编译错误:

cannot convert a (type bool) to type int   // 无法将 bool 类型转换为 int 类型
复制代码

2.4 字符串

Go语言中,字符串是一个不可改变的字节序列,类型为原生数据类型。准确的来说字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容,也可以说字符串是字节的定长数组。

2.4.1 定义字符串

Go语言中,字符串的值通过双引号来包裹的。字符串中可以使用转义字符来实现换行、缩进等效果。如下:

package main

import "fmt"

func main() {
    var str = "稀土掘金\n小黑豆豆"
    fmt.Println(str)
}
复制代码

运行结果为:

go语言简单 go语言入门指南_java

常用的转义字符还包括:

  • \n:换行符
  • \r:回车符
  • \t:tab 键
  • \u 或 \U:Unicode 字符
  • \\:反斜杠自身

2.4.2 字符串拼接符"+"

两个字符串s1s2可以通过s := s1 + s2拼接在一起。将s2追加到s1尾部并生成一个新的字符串s。如下:

str := "hello " + 
"world!"
复制代码

注意:因为编译器会在行尾自动补全分号,所以拼接字符串用的加号+必须放在第一行末尾。

也可以使用+=来对字符串进行拼接,如下:

str := "hello" + "world!"
str += "小黑"

fmt.Printf(str)
复制代码

go语言简单 go语言入门指南_java_02

2.4.3 定义多行字符串

如果想实现一个多行字符串时,就必须使用`反引号,代码如下:

var str = `第一行
第二行
第三行
...
`
fmt.Println(str)
复制代码

go语言简单 go语言入门指南_jvm_03

2.5 字符

Go语言中,字符串的每一个元素叫做字符,主要分为以下两种:

  1. uint8类型,或者叫byte型,代表了ASCII码的一个字符。
  2. rune类型,代表了一个UTF-8字符。通常情况下,当需要处理中文、日文、韩文等复合字符时,需要用到rune类型。

可以在 fmt.Println 中通过 %T 来输出变量的实际类型,代码如下:

package main 
import "fmt" 

func main() { 
    var a byte = 'd' 
    fmt.Printf("%d %T\n", a, a)

    var b rune = '豆'
    fmt.Printf("%d %T\n", b, b)
}
复制代码

运行代码结果如下:

go语言简单 go语言入门指南_go语言简单_04

由上可以得到:

  • byte的实际类型是个uint8,对应的ASCII编码为100
  • rune的实际类型其实是int32,对应的Unicode编码为35910

Go语言中,使用了rune类型来处理Unicode编码,这样让基于Unicode的文本处理更为方便,同时也可以用byte进行默认的字符串处理,这样对性能和拓展性都有照顾。

三、常量

Go语言中,常量在代码的编译期就已经确定了,而不是运行时。每种常量的潜在类型都是基础类型:booleanstring数字

3.1 定义&声明

Go语言中定义一个常量非常简单,它和变量的声明方式类似,只需将var关键字替换成const即可,代码如下:

const pi = 3.1415926
const url = "juejin.cn"

fmt.Println(pi, url)
复制代码

运行结果如下:

go语言简单 go语言入门指南_jvm_05

3.2 定义多个常量

常量也是可以同时定义多个的,方式和变量很类似,代码如下:

const (
    pi = 3.1415926 
    url = "juejin.cn"
)

fmt.Println(pi, url)
复制代码

运行结果也和上面一致。

最后,Go语言的基础语法的第一部分就介绍到这里,对于刚接触Go语言的我来说,一时半会儿还没有从js的代码习惯转过来,所以真的不是收藏即学会的。希望大家学完能有所收获!