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语言将数据类型分为四类:基础类型(如整型、浮点型、布尔型、字符型)、复合类型、引用类型和接口类型。
下面是一些常用的数据类型及其取值范围:
| 类型 | 描述 |
|---|---|
| uint | 32位或64位 |
| uint8 | 无符号 8 位整型 (0 到 255) |
| uint16 | 无符号 16 位整型 (0 到 65535) |
| uint32 | 无符号 32 位整型 (0 到 4294967295) |
| uint64 | 无符号 64 位整型 (0 到 18446744073709551615) |
| int | 32位或64位 |
| int8 | 有符号 8 位整型 (-128 到 127) |
| int16 | 有符号 16 位整型 (-32768 到 32767) |
| int32 | 有符号 32 位整型 (-2147483648 到 2147483647) |
| int64 | 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807) |
| byte | uint8的别名(type byte = uint8) |
| float32 | IEEE-754 32位浮点型数 |
| float64 | IEEE-754 64位浮点型数 |
| complex64 | 32 位实数和虚数 |
| complex128 | 64 位实数和虚数 |
数组
数组是一个由 固定长度 的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。
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)
}
流程控制
分为三类
- 顺序执行。这个非常简单,就是先执行第一行再执行第二行……这样依次从上往下执行。
- 选择执行。有些代码可以跳过不执行,有选择地执行某些代码。
- 循环执行。有些代码会反复执行。
条件语句
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 表示实例本身.