命名与包
-
变量名、函数名、常量名:采用驼峰命名;
-
变量名、函数名、常量名, 首字母大写,则可以被其他的包访问;首字母小写,则只能在本包中使用;
-
导入包需要使用双引号包裹起来;
-
导入包名是从 $GOPATH/src/
后开始计算的,路径使用/进行分隔;
-
GOPATH 是一个环境变量需要进行配置;
-
关键字:25个;预定义标识符:36个,包含基础数据类型和系统内嵌函数;
-
一般包的声明和所在的文件夹同名;(不同命也没问题)
-
在函数调用的时候要定位到所在的包;
-
一个目录下的统计文件不能有不同的 package
名;
-
一个目录下不能有重复的函数;main 特殊
-
在程序层面,所有使用相同 package
名的源文件组成一个模块;这也叫解释了上一项函数名不能重复
-
在(源)文件层面,就是一个文件夹;
-
import ( alais "xxx/xxx/pack")
起个别名;原来的包名不能再用了;
关于 ++/–
- go 中自操作只能单独使用,不能参与到运算中去;
- go 中自操作之呢个在变量的后面,不能在前面;写在前面语法错误;
接收键盘输入/终端输入
-
func Scanln(a ...interface{}) (n int, err error)
;
- 在换行是才停止扫描;最后一个条码后必须有换行或者到达结束位置;需要使用地址接收参数
-
func Scanf(format string, a ...interface{}) (n int, err error)
switch
- switch 后是一个表达式:常量,变量,一个有返回值的函数
- case 后的表达式如果为常量则不能重复;
- case 后的数据类型要和 switch 的表达式数据类型一致;
- case 后可以带多个值,使用逗号分隔;
- go 的case 后不需要带break;default 也不是必须的,位置也可以随意放置,不一定要在最后;
- switch 后不带表达式,当作if分支来使用;
- switch 后可以直接声明一个变量,分号结束
- 如果需要穿透,使用
fallthrough
关键字,默认只会穿透一个 case;
for 循环
函数
- 函数是go 语言的一等公民;
- 声明不需要顺序
- 基本数据类型、数组默认都是值传递;进行值拷贝。在函数内修改,不会影响到原来的值。
- 函数使用栈帧
- 如果要在函数内部修改传入的参数并影响入参的变量,可以使用变量的地址&,函数内以指针的方式操作变量。
- go 中函数也是一种数据类型,可以赋值给一个变量;被赋值的变量就是一个函数类型的变量。通过该变量可以和对函数调用;
- 函数可以作为形参,并且调用
- go 和 C 类似的的自定义数据类型:
type 自定义数据类型名 数据类型
;相当于起了一个别名;
type myFunType fun(int, int) int
- go 支持对函数返回值命名;
init 函数
- 顺序:1、全局变量的定义;2、init 调用;3、main 调用
匿名函数
- go 支持匿名函数,如果某个函数只希望使用一次,可以考虑使用匿名函数;
- 使用方式:
- 在定义匿名函数时就是直接使用,这种方式匿名函数只能调用一次;
- 将匿名函数赋值给一个变量,再通过该变量来调用匿名函数;
- 将一个匿名函数赋值给一个全局变量,可以在整个程序中有效/使用;
闭包
- 闭包就是一个函数和与其相关的引用环境组合的一个整体;
- 闭包的本质依旧时一个匿名函数;但是这个函数引入外界的变量/参数
- 闭包中的变量/参数会一直报存在内存中,所以会一直使用 -> 意味着闭包不可以滥用
defer
- 延迟执行;
- defer 后的语句会压入单独的栈;会将相关的值同时拷贝,不会随着函数后面的变化而变化;
- 用于函数执行完毕后及时释放资源;
时间日期
- 时间、日期函数,需要导入 time 包
- 格式化:
2006-01-02 15:04:05
: 各个数字是固定的必须这样写,自己开发的编程语言,就是这么随意;数字可以自由组合 2006 15:04
内置函数
- go 设计者为了编程方便,提供了一些函数,这些函数不用导包,可以直接使用,称为go 的内置函数;
- 内置函数位置:在
buildin
包下;
- 常用内置函数
-
len
: 统计字符串长度,按字节进行统计;
-
new
: 分配内存,主要用来分配值类型(int,float,bool,string, 数组,结构体);
-
make
: 分配内存,主要用来分配引用类型(指针,slice切片,map,管道chan,interface等);
defer+recover 机制处理错误
-
panic: runtime error:...
;
-
func New(text string) error
:类似于java 的 new Exception(String text)
;
数组
代码
package main
import (
"errors"
"fmt"
"math/rand"
"strconv"
"strings"
"time"
)
func main() {
fmt.Println("测试 Scanln 函数")
var age int
fmt.Println("input age:")
fmt.Scanln(&age)
fmt.Println("age=", age)
fmt.Println("Scanf input age name:")
var name string
_,_ = fmt.Scanf("%d %s", &age, &name)
fmt.Println("age=", age, ", name=", name)
fmt.Println(" switch 当作 if 来使用")
var a int32 = 2
switch {
case a == 1:
fmt.Println("a=1")
case a == 2:
fmt.Println("a=2")
//print("a=2")
}
fmt.Println("for 循环 测试")
var helloStr = "hello str"
for i := 0; i < len(helloStr); i++ {
fmt.Printf("%c \n", helloStr[i])
}
fmt.Println("for-range 循环 测试")
for i, val := range helloStr {
fmt.Printf("idx_is:%d, val_is:%c \n", i, val)
}
helloStr += "字符串"
for i, val := range helloStr {
fmt.Printf("idx_is:%d, val_is:%c \n", i, val)
}
fmt.Println(" 函数测试")
varFun := test
fmt.Printf("varFun's type is:%T, test function type is:%T\n", varFun, test)
varFun(123)
fmt.Println("go go go ==>>")
test02(1, 3.14, test)
test02(1, 3.14, varFun)
fmt.Println("测试自定义类型")
type myInt int
var num1 myInt = 30
fmt.Println("num1", num1)
fmt.Println("1、全局变量的定义;2、init 调用;3、main 调用: 测试")
fmt.Println("globalVar=", globalVar)
fmt.Println(" 匿名函数 测试")
res := func(num3 int, num4 int) int {
return num3 + num4
}(10, 20)
fmt.Println("res=", res)
fmt.Println(" 闭包展示")
f := getSum()
fmt.Println(f(1))
fmt.Println(f(2))
fmt.Println(f(3))
fmt.Println(" defer 案例演示:")
fmt.Println(deferTest(30, 60))
fmt.Println("===>>>字符串函数:")
str := "golang中文"
fmt.Println("str_len=", len(str))
r := []rune(str)
for i := 0; i < len(r); i++ {
fmt.Println(r[i])
}
// 字符串转整数:
num666, _ := strconv.Atoi("666")
fmt.Println(num666)
// 整数转字符串:
str1 := strconv.Itoa(88)
fmt.Printf("str1_type_is: %T, val_is: %v \n", str1, str1)
fmt.Println(" 统计字符串中的子串:")
count := strings.Count("golangandjavaga", "ga")
fmt.Println(count)
fmt.Println("不区分大小写的字符串比较:")
flag := strings.EqualFold("hello", "HELLO")
fmt.Println(flag)
fmt.Println("区分大小写的字符串比较:")
fmt.Println("hello" == "HeLlo")
// 字符串替换: n=-1表示全部替换;n=2 表示替换两个
replace := strings.Replace("goandjavagogo", "go", "golang-", 2)
fmt.Println(replace)
// 字符串分割 split
fmt.Println(strings.Split("go-python-java", "-"))
// 大小写转换
fmt.Println(strings.ToLower("Go"))
fmt.Println(strings.ToUpper("go"))
// 去掉字符串左右两边
fmt.Println(strings.TrimSpace(" go and java "))
// 去掉字符串左右两边指定的字符
fmt.Println(strings.Trim("##golang@@## ", "#"))
// 去掉字符串左边指定的字符
fmt.Println(strings.TrimLeft("##golang@@##", "#"))
// 去掉字符串右边指定的字符
fmt.Println(strings.TrimRight("##golang@@##", "#"))
// 判断是否以指定的字符串开头
fmt.Println(strings.HasPrefix("https://www.go.com", "http"))
// 判断是否以指定的字符串结束
fmt.Println(strings.HasSuffix("https://www.go.com", "cn"))
fmt.Println("==>> 时间日期函数测试:")
now := time.Now()
fmt.Printf("%v ==>> 对应的类型为:%T\n", now, now)
fmt.Printf("年: %v \n", now.Year())
fmt.Printf("月: %v \n", now.Month())
fmt.Printf("月_int: %v \n", int(now.Month()))
fmt.Printf("日: %v \n", now.Day())
fmt.Printf("时: %v \n", now.Hour())
fmt.Printf("分: %v \n", now.Minute())
fmt.Printf("秒: %v \n", now.Second())
fmt.Printf("%d-%d-%dT%d:%d:%d \n", now.Year(), now.Month(),
now.Day(), now.Hour(), now.Minute(), now.Second())
dateStr := fmt.Sprintf("%d-%d-%dT%d:%d:%d \n", now.Year(), now.Month(),
now.Day(), now.Hour(), now.Minute(), now.Second())
fmt.Println(dateStr)
fmt.Println("使用 Format")
format := now.Format("2006-01-02 15:04:05")
fmt.Println(format)
fmt.Println(now.Format("2006 15:04"))
fmt.Println("\n内置函数 [new, ]测试")
num := new(int)
fmt.Printf("num type is: %T, val is: %v, addr is: %v, 指针指向的值是:%v \n", num,
num, &num, *num)
fmt.Printf("\n defer+recover:")
deferRecover()
fmt.Println("go-go-go...")
err := errorsNewTest()
if err != nil {
fmt.Println("自定义错误", err)
//panic(err)
}
fmt.Println("continue-go...")
fmt.Println("\n 数组测试:")
var scores [5]int
scores[0] = 95
scores[1] = 91
scores[2] = 39
scores[3] = 60
scores[4] = 21
sum := 0
for i := 0; i < len(scores); i++ {
sum += scores[i]
}
fmt.Println("sum=", sum)
var arr [3]int16
fmt.Println("arr_len_is", len(arr))
fmt.Println("arr_is:", arr)
fmt.Printf("arr 地址为:%p \n", &arr)
}
func deferRecover() {
defer func() {
err := recover()
if err != nil {
fmt.Println("错误已经捕获")
fmt.Println("err_is:", err)
}
}()
num1 := 10
num2 := 0
result := num1 / num2
fmt.Println(result)
}
func errorsNewTest() (err error){
num1 := 10
num2 := 0
if num2 == 0 {
return errors.New("除数不能为0!")
} else {
res := num1/num2
fmt.Println(res)
return nil
}
}
func deferTest(num1 int, num2 int) int {
defer fmt.Println("num1=", num1)
defer fmt.Println("num2=", num2)
num1 += 10
num2 += 10
var sum int = num1 + num2
fmt.Println("sum=", sum)
return sum
}
func getSum() func(int) int {
var sum int = 0
return func(num int) int {
sum = sum + num
return sum
}
}
func test(num int) {
fmt.Println(num)
}
func test02(num1 int, num2 float32, funcVar func(int)) {
funcVar(num1)
fmt.Println("==>> test02")
}
type funIntType func(int)
func test03(num1 int, num2 float32, funcVar funIntType) {
funcVar(num1)
fmt.Println("==>> test03", num2)
}
func addXSub(num1 int, num2 int) (int, int) {
result01 := num1 + num2
result02 := num1 - num2
return result01, result02
}
func addXSub2(num1 int, num2 int) (sum int, sub int) {
sum = num1 + num2
sub = num1 - num2
return
}
var globalVar = varInit()
func varInit() int {
fmt.Println(time.Now(), ": varInit_call")
return rand.Int()
}
func init() {
fmt.Println(time.Now(), ": init_call")
}
输出
2022-01-24 22:05:15.6199452 +0800 CST m=+0.008090501 : varInit_call
2022-01-24 22:05:15.6527917 +0800 CST m=+0.040937001 : init_call
测试 Scanln 函数
input age:
17
age= 17
Scanf input age name:
18
age= 18 , name=
switch 当作 if 来使用
a=2
for 循环 测试
h
e
l
l
o
s
t
r
for-range 循环 测试
idx_is:0, val_is:h
idx_is:1, val_is:e
idx_is:2, val_is:l
idx_is:3, val_is:l
idx_is:4, val_is:o
idx_is:5, val_is:
idx_is:6, val_is:s
idx_is:7, val_is:t
idx_is:8, val_is:r
idx_is:0, val_is:h
idx_is:1, val_is:e
idx_is:2, val_is:l
idx_is:3, val_is:l
idx_is:4, val_is:o
idx_is:5, val_is:
idx_is:6, val_is:s
idx_is:7, val_is:t
idx_is:8, val_is:r
idx_is:9, val_is:字
idx_is:12, val_is:符
idx_is:15, val_is:串
函数测试
varFun's type is:func(int), test function type is:func(int)
123
go go go ==>>
1
==>> test02
1
==>> test02
测试自定义类型
num1 30
1、全局变量的定义;2、init 调用;3、main 调用: 测试
globalVar= 5577006791947779410
匿名函数 测试
res= 30
闭包展示
1
3
6
defer 案例演示:
sum= 110
num2= 60
num1= 30
110
===>>>字符串函数:
str_len= 12
g
o
l
a
n
g
中
文
666
str1_type_is: string, val_is: 88
统计字符串中的子串:
2
不区分大小写的字符串比较:
true
区分大小写的字符串比较:
false
golang-andjavagolang-go
[go python java]
go
GO
go and java
golang@@##
golang@@##
##golang@@
true
false
==>> 时间日期函数测试:
2022-01-24 22:05:27.8228879 +0800 CST m=+12.211033201 ==>> 对应的类型为:time.Time
年: 2022
月: January
月_int: 1
日: 24
时: 22
分: 5
秒: 27
2022-1-24T22:5:27
2022-1-24T22:5:27
使用 Format
2022-01-24 22:05:27
2022 22:05
内置函数 [new, ]测试
num type is: *int, val is: 0xc00000c548, addr is: 0xc000006030, 指针指向的值是:0
defer+recover:错误已经捕获
err_is: runtime error: integer divide by zero
go-go-go...
自定义错误 除数不能为0!
continue-go...
数组测试:
sum= 306
arr_len_is 3
arr_is: [0 0 0]
arr 地址为:0xc00000c568