目录
语法
warning
未完待续...
语法
类型转换
映射与切片对比
包
包是go代码的文件组织结构
- 通过
package
定义,使用import
导入 - 一次可以导入多个包
- 大写字母开头的属性可以被外部调用
main
包中的main
函数为程序的入口,可以编译并运行
// goguide/chapter2/utils/packages.go
// 定义包
package utils
// 导入包
import "fmt"
// 一次可以导入多个包
import (
"fmt"
"math"
)
// 大写字母开头的属性可以被外部调用
func PackageTest() {
fmt.Println("大写字母开头的属性可以被外部调用")
}
// goguide/chapter2/main.go
package main
import (
"3rcd.com/goguide/chapter2/utils"
)
// 入口函数
func main() {
utils.PackageTest()
}
函数
函数是go中唯一的代码逻辑包装器,go没有传统的面向对象中的类,方法等
函数定义语法
func {函数名}(...参数:类型) 返回值类型
注意
- 参数类型相同可以只写最后一个的类型
- 可以返回多个值,并且应该直接赋值而不需要初始化
- 可以把内部的变量返回出来,推荐用于内容较少的函数,否则影响阅读
- 与其它编程语言一样函数支持闭包和变量函数
- 与TS一样闭包函数可以作为返回值并支持透传
// goguide/chapter2/utils/funcs.go
package utils
// 参数类型相同可以只写最后一个的类型
func add(x, y int) int {
return x + y
}
// 可以返回 多个值
func swap(x, y string) (string, string) {
return y, x
}
// 可以把内部的变量返回出来
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
// 支持闭包函数和变量函数
func do(fn func(int, int) int) int {
total := fn(3, 4)
return total
}
func adder() func(int) int {
sum := 0
// 闭包函数可以作为返回值
return func(x int) int {
// 支持透传
sum += x
return sum
}
}
func main() {
ngm.Hello()
_, say := ngm.Sayname("nangongmo", "jikebianma")
println(say)
p := func(x, y int) int {
return x * y
}
fmt.Println(do(p))
x := adder()
fmt.Println(x(1), x(1))
}
变量与常量
变量使用var
或:=
初始化,常量使用const
定义
- 使用
var
声明,声明时初始化的变量可自动推导类型 - 可只初始化不赋值,如果始终不赋值则为零值(0,false,"")
- 一行可以声明多个变量
:=
可以快捷声明变量,:=
声明方式方式只在函数内有效- 声明变量可以是一个语法块
- 类型转换:把变量放入类型函数中即可(类型必须可转换)
var commentCount, postCount int
var (
isPublishied bool = false
categoryName string = "learn-go"
)
func Pvar() {
commentCount = 6
postCount = 7
c, python, java := true, false, "no!"
fmt.Println(float64(commentCount), postCount, isPublishied, categoryName, c, python, java)
}
逻辑
go的逻辑运算包括if
,else
,for
,switch
if
与for
的条件外围不需要加小括号()
for
初始化语句和后置语句是可选的- 没有
while
语句,用for
去除两端语句就是while
for
直接加大括号就是无限循环if
条件中可执行一个表达式,比如声明变量,此变量只在if
内部有效switch
不需要case
语句- 没有条件的 switch 同
switch true
一样 - 使用
defer
语句的函数会在所在函数全部执行完毕后再执行 defer
语句函数会按照后进先出的顺序调用
package main
import "fmt"
func main() {
defer fmt.Println("done")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
defer fmt.Println("counting")
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
sum = 1
for sum < 100 {
sum += sum
}
fmt.Println(sum)
// for {
// 无限循环
// }
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
fmt.Println("When's Saturday?")
today := time.Now().Weekday()
switch time.Saturday {
case today + 0:
fmt.Println("Today.")
case today + 1:
fmt.Println("Tomorrow.")
case today + 2:
fmt.Println("In two days.")
default:
fmt.Println("Too far away.")
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
指针
指针是一个变量的内存地址
- 使用
&{变量}
赋值一个指针,比如p = &i
,p
就是i
的内存地址 - 通过
*{指针变量}
获取这个变量的值 - 使用
var p *{类型}
可以初始化一个指针类型的变量
package main
import (
"fmt"
)
func main() {
x, y := 10, 15
s := &x
fmt.Println(*s)
*s = 20
fmt.Println(x)
s = &y
*s = *s / 5
fmt.Println(y)
}
结构体与映射
结构体类似ts中的对象类型,只是使用struct
定义的一组键值对
结构体语法:
// 定义结构体类型
type {结构体名称} struct {
{变量1} {类型1}
{变量2} {类型2}
}
// 定义零值变量
var i:{结构体名称}
// 直接初始化变量
i := {结构体名称}{{变量1值},{变量2值}}
映射是结构体的一个键值对集合,类似ts中的Map
映射语法
// 定义零值变量
var m map[{索引类型}]{值类型}
// 直接赋值
var m = map[索引类型]{值}
// 通过make创建一个实例
m = make(map[{索引类型}]{值类型})
使用delete({映射},{键名})
方法可通过键名删除映射一个元素
通过m[key]
来读取一个不存在的元素的时候将返回零值(nil
)
使用elem, ok := m[key]
读取一个不存在的键的时候elem
为零值,ok