Go 语言入门指南:基础语法和常用特性解析 (上)

变量和常量

首先我们需要知道变量跟常量的区别:变量是一个可变的值,而常量是一个恒定不变的值。

变量

变量的功能是存储数据,不同的变量保存的数据类型也不一样。我们常见的变量类型有整形(int)、浮点型(float)、布尔型(bool)等。

变量声明

Go语言中变量声明格式为:

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

声明变量需要以var开头,同时声明变量不需要分号结尾。举例:

go 复制代码
var name string
var age int8
var flag bool

go语言中支持批量声明变量

go 复制代码
var (
    name string
    age int8
    flag bool
)

变量初始化

go语言在声明变量时,会自动为变量对应的内存区域进行初始化,并且每个变量会被初始化为默认值。例如:整形和浮点型的默认值都是0;字符串默认值是空字符串;布尔值默认值是false;切片、函数、指针变量的默认值都是nil。 变量初始化格式:

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

变量初始化也可以一次初始化多个变量

go 复制代码
var name string = "zhangsan"
var age int8 = 18
var city,province string = "江苏", "苏州"

类型推导

我个人非常喜欢go语言中的这个类型推导,我们可以让编译器自动根据右值来推导出变量的类型,依此来完成初始化,甚至是在基于函数返回值的时候。当我们不确定具体需要什么类型时,我们也可以使用类型推导来完成变量初始化。

go 复制代码
var name = "zhangsan"
var age = 18

短变量声明

在函数内部使用类型推导时,我们可以将var省略,直接使用:=的方式来初始化变量,但是只能在函数内部使用,无法在函数外部使用。

go 复制代码
package main

import ("fmt")

func add(x, y int8) int8 {
    return x + y
}

//全局变量
var a := 100

func main() {
    //局部变量
    n := 10
    m := 20
    res := add(n, m)
    fmt.Println(res) //30
}

匿名函数

当一个函数有多个返回值时,而我们只需要其中一个值时,我们可以使用匿名函数。匿名函数使用一个下划线_来表示。_表示占位符,不会占用空间以及内存。

go 复制代码
package main

import ("fmt")

func two() (string, string){
    return "XXX", "YYY"
}

func main() {
    x, _ := two()
    _, y := two()
    fmt.Println("x=", x) //x=XXX
    fmt.Println("y=", y) //y=YYY
}

常量

常量声明

常量一般用于声明那些不会变的值,同时常量的使用与变量的使用几乎一致,只是将var换成了const,但是常量在声明时就必须赋值。

go 复制代码
const pi = 3.1415926
const (
    a = 100
    b = 200
)
//const在同时声明多个变量时,可以省略下面的值,如果省略了那么下面的值和其上面一行的值相同
const (
    a1 = 11
    a2
    a3
)
//此时a2,a3的值都是11,与a1相同

iota

iota是一个常量计数器,只能在常量中使用。 iota在const出现时就会重置为0,而const每额外声明一个常量,iota的值就会+1。

go 复制代码
const (
    a1 = iota //0
    a2        //1
    a3        //2
)

//我们也可以使用_来跳过中间值
const (
    b1 = iota //0
    b2        //1
    _
    b3        //3
)

//iota也可以用于中间插队
const (
    c1 = iota //0
    c2 = 222  //222
    c3 = iota //2
    c4        //3
)

基本数据类型

整型

go语言中的整型分为两类,一类是有符号的整型int,还有一类是无符号的整型uint

这里我们需要注意,在go语言中,我们在使用整型时,需要指定其大小,这也是go语言中一点非常讨厌。当我们在初始化一个变量时,我们需要考虑其在之后可能会占用的内存大小,如果考虑不当就会产生很多问题在Java中我们就不需要考虑这一点。如果我们不给其指定大小,那么intuint的大小就会按照操作系统的大小而定。32位的操作系统就会使其成为int32uint32;64位的操作系统就会使其成为int64uint64

这里我们需要注意,uint8类型就是我们常见的byte类型。而int32类型就是rune类型,rune类型代表一个UTF-8字符。

类型 描述
int 根据操作系统大小而定
int8 有符号的8位整型
int16 有符号的16位整型
int32 有符号的32位整型
int64 有符号的64位整型
uint 根据操作系统大小而定
uint8 无符号的8位整型
uint16 无符号的16位整型
uint32 无符号的32位整型
uint64 无符号的64位整型

浮点型

go语言中只有两种浮点型:float32float64float32就相当于Java中的float,而float64就相当于Java中的double,我们在声明浮点型时也需要考虑其可能使用的大小,否则会造成内存浪费。

复数

go语言中有两种复数,complex64complex128。复数有实部也有虚部,而实部和虚部的大小是一致的,例如complex64的实部和虚部大小都是32位,而complex128的实部和虚部大小都是64位。

go 复制代码
var a1 complex64
a1 = 1 + 2i
var a2 complex128
a2 = 3 + 4i
fmt.Println(a1) //(1+2i)
fmt.Println(a2) //(3+4i)

布尔值

go语言中的布尔值是bool类型,而布尔值数据也只有truefalse两个值。布尔类型的默认值是false。

go 复制代码
var flag bool
fmt.Println(flag) //false

字符串

go语言中的字符串的内部实现使用UTF-8编码,而字符串的值用""声明。

go 复制代码
s1 := "hello"
s2 := "go"
fmt.Println(s1, s2) //hello go

字符串转义符

如果想要在字符串中使用一些符号或者操作,需要使用其转义符。这些转义符在大部分语言中都是相同的,我这里就不多做说明了,讲三个常用的转义符:

转义符 含义
\r 回车符
\n 换行符
\t 制表符

多行字符串

在go语言中,我们想要定义一个多行字符串时,需要使用反引号声明。

go 复制代码
s1 := `aaa
bbb
ccc
`
fmt.Println(s1)
//输出结果
//aaa
//bbb
//ccc

字符串的常用操作

go语言中有一些字符串的常用操作,这使得我们在字符串的使用上非常便捷。

方法 介绍
len(str) 求长度
+ 或 fmt.Sprintf 拼接字符串
strings.Split 分割
strings.contains 判断是否包含
strings.HasPrefix,strings.HasSuffix 前缀/后缀判断
strings.Index(),strings.LastIndex() 子串出现的位置
strings.Join(a[]string, sep string) join操作

类型转换

go语言中有强制类型转换,没有隐式类型转换。但是我们需要注意,这里的强制类型转换,不是让我们将布尔值转换成整型值,这是不合理的,我们需要在其合理的范围内进行转换。

go 复制代码
T(表达式)

这里的T表示要转换的类型;而表达式表示需要转换的值,包括变量、函数返回值等。

go 复制代码
a1 := 3.33
a2 := 4.44
a3 := int8(a1+a2)
fmt.Println(a3) //7

运算符

go语言中内置的运算符有:

  1. 算术运算符
  2. 关系运算符
  3. 逻辑运算符
  4. 位运算符
  5. 赋值运算符

算数运算符

运算符 描述
+ 相加
- 相减
* 相乘
/ 相除
% 求余
注意:++表示自增,--表示自减。这是单独的语句,在go语言中不是运算符。

关系运算符

运算符 描述
== 2==3 false
!= 2!=3 true
> 2>3 false
>= 2>=3 false
< 2<3 true
<= 2<=3 true

逻辑运算符

运算符 描述
&& 逻辑AND运算符。两边都为true,结果则为true
|| 逻辑OR运算符。两边有一个为true,结果就是true
! 逻辑NOT运算符。条件为true,则为false

位运算符

位运算符用于对整数在内存中的二进制进行操作。

运算符 描述
& 参与运算的两数各对应的二进制相与(两位均为1才为1)
| 参与运算的两数各对应的二进制相或(两位有一个为1就为1)
^ 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(两位不一样则为1)
<< 左移n位就是乘以2的n次方。 "a<<b"是把a的各二进位全部左移b位,高位丢弃,低位补0。
>> 右移n位就是除以2的n次方。 "a>>b"是把a的各二进位全部右移b位。

赋值运算符

运算符 描述
= x = y
+= x+=y  x=x+y
-= x-=y  x=x-y
*= x*=y  x=x*y
/= x/=y x=x/y
%= x%=y x=x%y
<<= x<<=y x=x<<y
>>= x>>=y x=x>>y
&= x&=y x=x&y
|= x|=y x=x|y
^= x^=y x=x^y

流程控制

每种语言中都需要控制整体逻辑的走向以及各部分的先后排序,而我们正是通过流程控制符来完成这一需求。

在go语言中,for是万能的。以Java举例,go语言中的for不仅拥有Java语言中的for功能,还拥有Java语言中的while功能。go语言中常用的流程控制符有forif,go语言中还有switchgoto两种流程控制符,但是使用不多,主要是为了简化代码,降低重复代码而使用的。

if else(分支结构)

go语言中if条件判断的格式如下:

go 复制代码
if 表达式1 {
    分支1
} else if 表达式2 {
    分支2
} else {
    分支3
}

当表达式1的结果为true时,就会执行分支1,反之则会判断表达式2,如果都不满足,则会执行分支3的代码。

go语言的if条件判断省略掉了表达式两边的括号,使得代码十分简洁。但是go语言中有个规定,那就是{必须与if/else if 表达式/else在同一行,否则会编译失败。

go 复制代码
func ifDemo() {
    score := 90
    if score > 90 {
        fmt.Println("A")
    }else if score >= 80 {
        fmt.Println("B")
    }else if score >= 70 {
        fmt.Println("C")
    }else if score >= 60 {
        fmt.Println("D")
    }else{
        fmt.Println("E")
    }
}

for(循环结构)

go语言中所有的循环结构都用for来实现。

for循环的基本格式:

go 复制代码
for 初始语句;条件表达式;结束语句{
    循环体语句
}

条件表达式返回true时就会一直执行,直到返回false停止。

go 复制代码
for forDemo() {
    for i:=0;i<3;i++ {
        fmt.Println(i)
    }
    
    //for循环的初始语句和结束语句也可以被省略掉
    i := 0
    for ;i<3;i++ {
        fmt.Println(i)
    }
    for i<3 {
        fmt.Println(i)
        i++
    }
}

go语言中的for还充当着其他语言中while的作用。

go 复制代码
func forDemo() {
    for {
        //无限循环体
    }
}

go语言中的for还有另外一种用法,for range,一般用于遍历数组、切片、字符串、map和通道。使用for range一般用于获取索引和值,键和值以及通道内的值。

go 复制代码
func forDemo() {
    m := []int{1,2,3}
    for i, v := range m {
        fmt.Println(i, v) 
        //i表示索引,v表示值
    }
}

switch case(条件判断)

go语言中switch用法与其他语言类似,然而go语言中的case可以有多个值,但是只能有一个default。go语言的case还可以使用一个表达式来代替,这使得switch的效率大大提升。

go 复制代码
func switchDemo() {
    s := 2
    switch s {
    case 1:
        fmt.Println("a")
    case 2:
        fmt.Println("b")
    case 3:
        fmt.Println("c")
    }
    
    switch n:=3; n {
    case 1,3,5,7,9:
        fmt.Println("奇数")
    case 2,4,6,8:
        fmt.Println("偶数")
    }
    
    switch score:=80; score {
        case score>=60:
            fmt.Println("合格")
        case score<60:
            fmt.Println("不合格")
    }
    
}

go语言中还有一个fallthrough语法,可以执行满足条件的case的后面一个case。

go 复制代码
func switchDemo() {
    s := "a"
    switch {
    case s=="A":
        fmt.Prinltn("A")
        fallthrough
    case s=="B":
        fmt.Println("B")
    case s=="C":
        fmt.Println("C")
    }
    //输出结果:
    //A
    //B
}

goto(跳转到指定标签)

goto在go语言中用于代码跳转,使用goto可以快速跳转到其他代码,常用于快速结束循环、避免重复退出。

go 复制代码
func gotoDemo() {
    flag := true
    i := 0
    for flag {
       fmt.Println(i)
       i++
       if i==3 {
          goto flagTag
       }
    }
    flagTag :
       flag = false
}

break和continue

breakcontinue在go语言中的语法与其他语言几乎一致。break一般用于结束循环的使用,常用于一段代码中找到结果时直接进行break结束即可。continue一般用于结束当前循环使用,常用于当前结果不符合我们预期的结果时,我们可以使用continue来跳过当前循环,进行下一轮循环。

go 复制代码
func break_continue() {
    for i:=0;;i++ {
        if i==3 {
            fmt.Println(i)
            break
        }
    }
    //输出结果:
    //3
    
    for i:=0;i<5;i++ {
        if i%2==0 {
            continue
        }
        fmt.Println(i)
    }
    //输出结果:
    //1
    //3
}

小结

到目前为止,我们认识了go语言中的基础语法使用,包括变量、常量声明、基本数据类型、运算符的使用以及流程控制符。希望小伙伴们能够有所收获。当然,go的基础语法还远不止这些,敬请收看下篇《Go 语言入门指南:基础语法和常用特性解析 (中) 》。

码字不易,如果您看到了这里,听我说谢谢您。

如果您觉得本文还不错,还请留下您小小的赞。

如果您看了本文有所感受,还请留下您宝贵的评论。

相关推荐
千慌百风定乾坤7 小时前
Go 语言入门指南:基础语法和常用特性解析(下) | 豆包MarsCode AI刷题
青训营笔记
FOFO7 小时前
青训营笔记 | HTML语义化的案例分析: 粗略地手绘分析juejin.cn首页 | 豆包MarsCode AI 刷题
青训营笔记
滑滑滑2 天前
后端实践-优化一个已有的 Go 程序提高其性能 | 豆包MarsCode AI刷题
青训营笔记
柠檬柠檬2 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户967136399652 天前
计算最小步长丨豆包MarsCodeAI刷题
青训营笔记
用户52975799354723 天前
字节跳动青训营刷题笔记2| 豆包MarsCode AI刷题
青训营笔记
clearcold3 天前
浅谈对LangChain中Model I/O的见解 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵4 天前
【字节青训营】 Go 进阶语言:并发概述、Goroutine、Channel、协程池 | 豆包MarsCode AI刷题
青训营笔记
用户336901104444 天前
数字分组求和题解 | 豆包MarsCode AI刷题
青训营笔记
dnxb1234 天前
GO语言工程实践课后作业:实现思路、代码以及路径记录 | 豆包MarsCode AI刷题
青训营笔记