Go语言入门 | 青训营

60 阅读9分钟

Go语言入门

基本语法

在go语言中可以使用四种声明语句:var(变量),const(常量),type(类型),func(函数)

//1.声明后赋值
var x int//var 变量名 类型
x=1
//2.var 变量名 类型 = 表达式
var x int =1
//3.短声明  变量的类型通过表达式自动推导
x:=1
x:="1"

由于简洁和灵活的特点,简短变量声明被广泛用于大部分的局部变量的声明和初始化。

根据以上内容,应记住“:=”是一个变量声明语句,而“=”是一个变量赋值操作。

常量可以通过const关键字来定义

const PI =123123

基础数据类型

Go语言将数据类型分为四类:基础类型(如整型、浮点型、布尔型、字符型)、复合类型、引用类型和接口类型。

下面是一些常用的数据类型及其取值范围:

类型描述
uint32位或64位
uint8无符号 8 位整型 (0 到 255)
uint16无符号 16 位整型 (0 到 65535)
uint32无符号 32 位整型 (0 到 4294967295)
uint64无符号 64 位整型 (0 到 18446744073709551615)
int32位或64位
int8有符号 8 位整型 (-128 到 127)
int16有符号 16 位整型 (-32768 到 32767)
int32有符号 32 位整型 (-2147483648 到 2147483647)
int64有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
byteuint8的别名(type byte = uint8)
float32IEEE-754 32位浮点型数
float64IEEE-754 64位浮点型数
complex6432 位实数和虚数
complex12864 位实数和虚数

数组

数组是一个由 固定长度 的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。

package main
import "fmt"
func main()
{
    var a[5]int//var变量名[n]type n表示数组中元素的数量, type表示每个元素的类型
    fmt.Println(a)//声明时没有指定数组元素的值, 默认为零值
    
    a[0]=1
    a[1]=2
    fmt.Println(a)
    //可以通过len(a)来获取数组的长度
    x:+=len(a)
    fmt.Println(x)
}

切片(Slice)

切片是对数组的一个连续片段的引用,所以切片是一个引用类型。切片 本身不拥有任何数据,它们只是对现有数组的引用,每个切片值都会将数组作为其底层的数据结构。slice 的语法和数组很像,只是没有固定长度而已。

// 声明整型切片
var numList []int// 声明一个空切片
var numListEmpty = []int{}
​
//make([]type, size, cap) 类型 长度 容量
numList:=make([]int,3,5)

Map

map 是散列表(哈希表)的引用。它是一个拥有键值对元素的无序集合,在这个集合中,键是唯一的,可以通过键来获取、更新或移除操作。

// 创建一个键类型为 string 值类型为 int 名为 s 的 map
s := make(map[string]int)
//添加元素
s["12"]=1
//更新元素
s["12"]=12

range关键字

在Go语言中,range关键字可以用于遍历数据结构中的元素。range关键字返回两个值,第一个值是当前元素的索引或键,第二个值是当前元素的值。使用range关键字可以简化遍历数据结构的代码,提高代码的可读性和可维护性。

nums := []int{1, 2, 3}
​
for i,v :=range arr{
    fmt.Println(i,v)
}
​

结构体

结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员。

struct Student{
    Id int
    Name string
    Phone string
}
​
var Student Student
//两个语句声明了一个叫Student的命名的结构体类型,并且声明了一个Student类型的变量Student:

JSON

JavaScript对象表示法(JSON)是一种用于发送和接收结构化信息的标准协议。JSON是对JavaScript中各种类型的值——字符串、数字、布尔值和对象——Unicode本文编码。

下面是JSON的格式

type Movie struct {
    Title  string
    Year   int  `json:"released"`
    Color  bool `json:"color,omitempty"`
    Actors []string
}
​
var movies = []Movie{
    {Title: "Casablanca", Year: 1942, Color: false,
        Actors: []string{"Humphrey Bogart", "Ingrid Bergman"}},
    {Title: "Cool Hand Luke", Year: 1967, Color: true,
        Actors: []string{"Paul Newman"}},
    {Title: "Bullitt", Year: 1968, Color: true,
        Actors: []string{"Steve McQueen", "Jacqueline Bisset"}},
    // ...
}

在go语言中可以将一个类似Movie类型的结构体通过转为JSON的过程叫编组(marshling)编组通过调用json.Marshal函数完成:

​
data, err := json.Marshal(movies)
if err != nil {
    log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Printf("%s\n", data)

这种紧凑的表示形式虽然包含了全部的信息,但是很难阅读。为了生成便于阅读的格式,另一个json.MarshalIndent函数将产生整齐缩进的输出。

data, err := json.MarshalIndent(movies, "", "    ")
if err != nil {
    log.Fatalf("JSON marshaling failed: %s", err)
}
fmt.Printf("%s\n", data)

String

转 义 字 符含 义
\r回车符 return,返回行首
\n换行符 new line, 直接跳到下一行的同列位置
\t制表符 TAB
'单引号
"双引号
\反斜杠
var study string    // 定义名为study的字符串类型变量
study = "123"       // 将变量赋值
​
study2 := "12314"   // 以自动推断方式初始化

函数

函数声明

函数声明包括函数名、形式参数列表、返回值列表(可省略)以及函数体

func grade(x int)(bool){ //func name(形参)(返回值){body}
    if x>90{
        return true
    }
    return false
}
​
func sum(x,y int)int{
    return x+y
}
func print() {
    fmt.Println("1234")
}
​
func main()
{
    x:=10
    b:=grade(x)
    fmt.Println(b)
    fmt.Println("10+2=",sum(10,2))
    print()
}
//当函数没有返回值时,函数体可以使用 return 语句返回。在 Go 中一个函数可以返回多个值。

可以传入多个类型不一致的参数

package main
​
import "fmt"func PrintType(args ...interface{}) {
    for _, arg := range args {
        switch arg.(type) {
        case int:
            fmt.Println(arg, "type is int.")
        case string:
            fmt.Println(arg, "type is string.")
        case float64:
            fmt.Println(arg, "type is float64.")
        default:
            fmt.Println(arg, "is an unknown type.")
        }
    }
}
​
func main() {
    PrintType(57, 3.14, "123")
}

匿名函数

没有名字的函数就叫 匿名函数 ,它只有函数逻辑体,而没有函数名。匿名函数只拥有短暂的生命,一般都是定义后立即使用。

func (parameter) (result) {
    body
}

内部方法与外部方法

在 Go 语言中,函数名通过首字母大小写实现控制对方法的访问权限。

当方法的首字母为 大写时,这个方法对于所有包 都是 Public,其他包可以随意调用。

当方法的首字母为 小写时,这个方法是 Private,其他包是无法访问的。

包(package) 用于组织 Go 源代码,提供了更好的可重用性与可读性。

package main
​
import "fmt"func main() {
    fmt.Println("123")
}

package name 表示指定了这个文件属于哪个包。package main 表示属于main包,import "fmt"表示导入一个已经存在的fmt包

创建包

属于一个包的源文件都应该放置在一个单独命名的文件夹中,一般用文件夹名做为包名。

// Package grade
package grade
​
func Sum(x,y int) (int) {//函数名大写可以供外部调用
  return x+y
}

导入包

导入包的语法为 import path ,其中 path 可以是相对于工作区文件夹的相对路径,也可以是绝对路径。

package main
​
import (
    "fmt"
    "grade"
)
​
func main() {
    x:=grade.Sum(1,3)
    fmt.Println(x)
}

流程控制

分为三类

  1. 顺序执行。这个非常简单,就是先执行第一行再执行第二行……这样依次从上往下执行。
  2. 选择执行。有些代码可以跳过不执行,有选择地执行某些代码。
  3. 循环执行。有些代码会反复执行。

条件语句

if 条件1 {
  逻辑代码1
} else if  条件2 {
  逻辑代码2
} else if 条件 ... {
  逻辑代码 ...
} else {
  逻辑代码 else
}

选择语句

switch 表达式 {
    case 表达式值1:
        逻辑代码1
    case 表达式值2:
        逻辑代码2
    case 表达式值3:
        逻辑代码3
    case 表达式值 ...:
        逻辑代码 ...
    default:
        逻辑代码
}

switch 语句是一个选择语句,用于将 switch 后的表达式的值与可能匹配的选项 case后的表达式进行比较,并根据匹配情况执行相应的代码块,执行完匹配的代码块后,直接退出 switch-case 。如果没有任何一个匹配,就会执行 default 的代码块。它可以被认为是替代多个 if-else 子句的常用方式。

循环语句

// for 接三个表达式
for init; condition; post {
   code
}
​
// for 接一个条件表达式
for condition {
   code
}
​
// for 接一个 range 表达式
for range_expression {
   code
}
​
​

break 语句

break 语句用于终止 for循环,之后程序将执行在for循环后的代码。上面的例子已经演示了 break 语句的使用。

continue 语句

continue 语句用来跳出 for 循环中的当前循环。在 continue语句后的所有的 for循环语句都不会在本次循环中执行,执行完 continue`语句后将会继续执行一下次循环。下面的程序会打印出 10 以内的奇数。

for num := 1; num <= 10; num++ {
    if num % 2 == 0 {
        continue
    }
    fmt.Println(num)
}

defer 延迟调用

含有 defer 语句的函数,会在该函数将要返回之前,调用另一个函数。简单点说就是 defer 语句后面跟着的函数会延迟到当前函数执行完后再执行。

package main
​
import "fmt"func Print() {
    fmt.Println("123")
}
​
func main() {
    defer Print()
    fmt.Println("main")
}
//先执行main函数后执行Print

方法

方法 其实就是一个函数,在 func 这个关键字和方法名中间加入了一个特殊的接收器类型。接收器可以是结构体类型或者是非结构体类型。接收器是可以在方法的内部访问的。

package main
​
import "fmt"type Student struct {
    Name   string
    Target string
}
​
func (student Student) PrintInfo() {
    fmt.Println("name:", student.Name)
    fmt.Println("target:", student.Target)
}
​
​
func main() {
    l := student.Student{
        Name: "张三",
        Target: "10",
    }
    l.PrintInfo()
}

上面创建了一个与结构体Student绑定的方法PrintInfo(),这里我们把 Student 称为方法的接收者,而 student 表示实例本身.