Go 语言入门指南:基础语法 | 青训营

69 阅读5分钟

前面的话

Go 语言是类C语言,C语言在逻辑上是完全信任程序员,而Go在这之上省去了很多程序员浪费开发时间的繁琐步骤。思想上就是 Less can be more 让事情变得复杂很容易,让事情变得简单才难。

基础语法

包声明

.go 文件的第一行就是包的声明,每个文件夹下只能有一个包名。

package helloworld

其中比较特别的是 main 包。在一个正常程序中,只有 main 包能运行。

包导入

Go 语言通过 import 关键字导入其他的包。主要有四种导入格式:

import (
    "fmt"
    myfmt "fmt"
    _ "fmt"
    . "fmt"
)
  1. 第一种就是正常导入,以 fmt 为包名使用该包下的可导出函数、常量。
  2. 第二种是别名形式,以 myfmt 为包名使用该包下的可导出函数、常量。
  3. 第三种表示不使用该包,而仅仅让该函数的 init 方法运行一下,并不显示的使用该包的其他内容。常在一些 driver 包中见到。(因为 Go 语言中不允许未使用的变量、导入包存在)
  4. 第四种直接将该包下的函数导入当前包中,如 fmt.Printf 可以直接用 Printf 调用。

常用变量类型

  • 布尔: 值类型,bool 值域只有 truefalse,默认值为 false

    • 可以通过基本的逻辑运算符 && || ! == != 进行运算与赋值。
  • 整型: 值类型,int8/uint8(byte) int16/uint16 int32(rune)/uint32 int int64/uint64,按字节数大小递增,只能赋予整数/正整数类型,默认值为0。

    • 常用整型为 byteintbyte 用于表示字符,而 int 字节数大小不确定,具体大小是跟机器的 CPU 位数相关的。如果 CPU 是 32 位的,那么 int 就占 4 字节,如果 CPU 是 64 位的,那么 int 就占 8 字节。
  • 浮点数: 值类型,float32 float64 能赋予整数和浮点数,但精度较低。默认值为0.0,通常使用 float64

  • 字符串: 值类型,string,声明后字符串本身不可修改,但变量可重新赋值,默认值为空字符串""

  • 结构体: 值类型 struct,需自己定义。所有空结构体只占用 Go 程序中的一个空间。

  • 数组: 值类型,带有 [ArraySize] 进行声明的基本类型, ArraySize 是常量,不可拓展。

  • 切片: 引用类型,带有 [] 进行声明的基本类型,可拓展。一般来说通常用切片替代数组,默认值为 nil

  • 哈希: 引用类型,map[T]VT 类型为键,V 类型为值,默认值为 nil

  • 通道: 引用类型,带有 chan 进行声明的类型,默认值为 nil

  • 接口: 接口类型,interface,默认值为 nilGo 语言中所有类型都算实现了空接口 interface{},因此任何值都可以赋给 interface{} 类型的变量。

  • 函数: 函数类型,默认值为 nil,具体类型根据函数签名确定。

  • 值类型在函数调用时会被拷贝,即使修改也不会影响原变量,而引用类型在函数调用时会影响到原变量。

  • 接口类型在传参时如果表示的是值类型,不影响原变量,如果表示引用类型,会影响原变量

  • 函数本身如果是闭包的,该闭包值会被影响

变量声明

var name string 
name := ""

变量声明有两种方法:

  • var 关键字声明。
    • 可以在函数体外使用
    • 主动声明类型
  • := 运算符直接赋值。
    • 无法在函数体外使用
    • Go 语言自动进行类型推断,可以直接接收函数返回值
    • 能在一些控制语句中临时定义变量
    • 运算符左侧至少要有一个未声明过的变量
    • 运算符右侧是数值常量时,默认使用 intfloat64 为变量类型

流程控制

  • if else switch 进行一次分支判断
  • for 进行循环
  • break continue 控制循环

for 关键字支持三种格式

  • for init ; condation ; body_next {body} 逻辑上运行顺序为 init -> condation -> body -> body_next -> condation -> body -> ... -> !condation
    • init 只执行一次,可以进行赋值和短变量声明
    • condation 运行结果必须为布尔类型,每次循环开启前都会进行一次判断
    • body 中执行 continue 语句会直接跳转到 body_next,执行 break 语句会直接中断循环
    • body_next 只能是简单的赋值语句
  • for condation {body} 简化代码,简去了 initbody_next 的执行
  • for {} 死循环代码,直到运行 break 语句才跳出循环

函数定义

Go 语言的函数有以下特点:

  • 无需声明原型。
  • 支持不定变参。
  • 支持多返回值。
  • 支持返回参数的命名。
  • 支持匿名函数和闭包。
  • 函数也是一种类型,一个函数可以赋值给相同签名的变量。

函数的声明主要由函数名,参数列表,返回值列表和函数体组成。

func main() {
    ok := HelloWorld("fff", "lmx", "jhm")
    fmt.Println(ok)
}

func HelloWorld(name string, otherNames ...string) (helloOK bool) {
    fmt.Printf("Hello %s and %v\n", name, otherNames)
    return true
}

// output: Hello fff and [lmx jhm]
// output: true
  • func 是函数声明
  • HelloWorld 是函数名
  • (name string, otherNames ...string) 是参数列表
    • otherNames 接收其他的不定变参,将其组成一个切片 slice
  • (helloOK bool) 是返回值列表
  • {} 内的是函数体

其中参数列表和返回值列表都是可以省略的,可以化简化为如下等签名形式(参数声明后一定要被使用,或用占位符 _ 替换该参数名):