??main包申明的程序是可运行的。 包是函数和数据的集合,将有相关的鹅的函数和数据放在统一的文件目录进行管理,每个包都可以作为独立的单元维护并提供给其他的项目 进行使用。 声明:
GO源文件都需要在开头使用package声明所在的包,包名告知编译器哪些包的源代码用于编译库文件,其次包名用于限制包内成员包内成员对外的可见性,最后包名用于在包外对公开成员的访问 包名使用简短的小写字母,常与所在的目录名保持一致,一个包中可以由多个 go源文件,但是必需使用相同的包名。
在Go语言里面是通过首字母的大小写来定位包外部可不可以被访问 。
main包与main函数 main包用于声明告知编译器将包编译为二进制可执行文件 在main包中的main函数是程序的入口,无返回值,无参数
init函数 init函数是初始化包的时候使用的, 无返回值,无参数,建议每个包只定义一个,init函数在import包时自动调用,(const -> var ->init )
GOPATH + vendor 机制 vendor 将项目依赖的包拷贝到项目下的vendor 目录,在编译时使用项目下的vendor目录中的包进行编译 解决问题: 依赖的外部包过多,在使用第三方包的时候需要go get进行下载 第三方包在go get下载后不能保证开发和编译时版本的兼容 。 包 搜索顺序 在当前包上级目录下查找GOPATH/src/vendor目录 在GOPATH目录下查找 在GOROOT目录下查找
第三方包 可以借助go get工具下载和安装第三方包及其依赖,需要安装与第三方包匹配的代码管理工具,比如git svn 等 常用参数: -d :仅下载依赖包 -u: 更新包并安装 -x: 打印执行的命令 -v:打印构建的包 -insecure : 允许使用http协议下载包、 第三方包查找的地址 : https://godoc.org https://gowalker.org/
包-Go包管理 Go modules 机制 优势 : 不用设置 GOPATH ,代码可以任意放置 自动下载依赖管理 版本控制 不允许使用相对导入 replace机制
go mod tidy:整理依赖模块(添加,新增的,删除,未使用) go mod vendor 将依赖的模块拷贝到模块的vendor目录 go build :编译当前模块 go build ./… : 编译当前目录下的所有模块 go build -mod = vendor :使用当前模块下的vendor目录的包进行编译 go mod download :仅下载第三方模块 go mod grapha : 打印第三方模块 go list -m -json all :显示所有 的模块 go mod edit :修改go.mod文件 -require =pakcage@version -replace =old_package@version=new_package@version 可以使用-replace功能将包替换为本地包,实现相对导入功能
单元测试-Test函数 测试函数需要导入testing包,并 编写代码
目录结构
package calc
func AddXXX(x, y int) int {
if x < 0 {
return x + y
} else {
return x
}
}
func Multi(x, y int) int {
return x * y
}
package calc
import (
"testing"
)
func TestAdd(t *testing.T) {
if 4 != AddXXX(1, 3) {
t.Error(" 1 + 3 != 4 ")
}
}
func TestAddFlag(t *testing.T) {
if -1 != AddXXX(-1, 3) {
t.Error("不相同")
}
}
go test ./… -coverprofile=cover.out
【结果输出】 ? go_learn/20211104/codes/src/testcalc [no test files] — FAIL: TestAdd (0.00s) calc_test.go:9: 1 + 3 != 4 — FAIL: TestAddFlag (0.00s) calc_test.go:16: 不相同 FAIL coverage: 75.0% of statements FAIL go_learn/20211104/codes/src/testcalc/calc 0.004s FAIL
go tool cover -html cover.out 展示75%的代码覆盖率
命令行参数
package main
import (
"flag"
"fmt"
)
func main() {
var port int
// 绑定命令行参数与变量关系
var host string
var help bool
flag.IntVar(&port, "P", 22, "ssh port")
flag.StringVar(&host, "H", "127.0.0.1", "请输入ip")
flag.BoolVar(&help, "h", false, "help")
flag.Usage = func() {
fmt.Println("usage flag arsg [-H 127.0.0.14 ] [-P 22][-v]")
flag.PrintDefaults()
}
// 解析命令行参数
flag.Parse()
fmt.Println(help)
if help {
fmt.Println("-------------------")
flag.Usage()
} else {
fmt.Println(host, port)
fmt.Println(flag.Args())
}
}
package main
import (
"flag"
"fmt"
)
func main() {
port := flag.Int("P", 22, "ssh port")
host := flag.String("H", "127.0.0.1", "请输入ip")
help := flag.Bool("h", false, "help")
fmt.Printf("%T %T %T \n", *port, *host, *help) // int string bool
flag.Usage = func() {
fmt.Println("usage flag arsg [-H 127.0.0.14 ] [-P 22][-v]")
flag.PrintDefaults()
}
// 解析命令行参数
flag.Parse()
fmt.Println(help)
if *help {
fmt.Println("-------------------")
flag.Usage()
} else {
fmt.Println(host, port)
fmt.Println(flag.Args())
}
}
go run flagargsv1.go -h -P 22
时间
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Printf("%T \n", now) //time.Time
fmt.Printf("%v \n", now) //2021-11-07 16:45:30.621285 +0800 CST m=+0.000053567
// 2000/01/02 08:10:10
// 2006年
// 01月
// 02天
// 24进制小时 15
// 分钟 04
// 秒 05
fmt.Println(now.Format("2006/01/02 15:04:05")) //2021/11/07 16:45:30
fmt.Println(now.Format("2006-01-02 15:04:05")) //2021-11-07 16:45:30
fmt.Println(now.Format("2006-01-02")) //2021-11-07
fmt.Println(now.Format("15:04:05"))
fmt.Println(now.Unix()) //1636274730
fmt.Println(now.UnixNano()) //1636274730621285000
xx, err := time.Parse("2006/01/02 03:04:05", "2006/01/02 03:04:05")
fmt.Println(err, xx) // 2006-01-02 03:04:05 +0000 UTC
t := time.Unix(0, 0)
fmt.Println(t) //1970-01-01 08:00:00 +0800 CST
d := now.Sub(t)
fmt.Println(d) //454520h51m59.778108s
fmt.Printf("%T \n", d) //time.Duration
// time.Second
// time.Hour
// time.Minute
// timeMillisecond
fmt.Println(time.Now()) //2021-11-07 16:54:33.066575 +0800 CST m=+0.000369435
time.Sleep(time.Second * 1)
fmt.Println(time.Now()) //2021-11-07 16:54:38.070339 +0800 CST m=+5.004314271
now3 := now.Add(time.Hour * 3)
fmt.Println(now, now3) //2021-11-07 16:55:47.174147 +0800 CST m=+0.000093460 2021-11-07 19:55:47.174147 +0800 CST m=+10800.000093460
d, err = time.ParseDuration("3h2m4s")
fmt.Println(err, d) // 3h2m4s
fmt.Println(d.Hours()) //3.0344444444444445
fmt.Println(d.Minutes()) //182.06666666666666
fmt.Println(d.Seconds()) //10924
}
hash算法
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
)
func main() {
x := md5.Sum([]byte("i amkk"))
y := fmt.Sprintf("%X \n", x)
fmt.Println(y)
//
z := hex.EncodeToString(x[:])
fmt.Println(z)
m := md5.New()
m.Write([]byte("i"))
m.Write([]byte(" amkk"))
fmt.Printf("%x\n", m.Sum(nil))
}
base64
package main
import (
"encoding/base64"
"fmt"
)
func main() {
x := base64.StdEncoding.EncodeToString([]byte("i am kk"))
fmt.Println(x)
bytes, err := base64.StdEncoding.DecodeString(x)
fmt.Println(string(bytes), err)
}
日志 :
package main
import "log"
func main() {
log.Printf("我是一个人")
log.Printf("我是一个人")
log.SetFlags(log.Flags() | log.Lshortfile) //prefix2021/11/07 20:30:46 logx.go:15: 我是fatalf日志z
//log.SetFlags(log.Flags() | log.Llongfile)
log.SetPrefix("prefix") //在日志前面加上前缀 prefix2021/11/07 20:29:59 /Users/quyixiao/go/src/go_learn/20211107/logx/logx.go:14: 我是fatalf日志z
//打印一个日志,并且触发一个panic
//log.Panicf("我是panic日志 :%s","y")
log.Fatalf("我是fatalf日志%s", "z")
log.Fatalf("我是fatalf日志%s", "z") //打印之后直接退出
}
2021/11/08 11:35:48 我是一个人 2021/11/08 11:35:48 我是一个人 prefix2021/11/08 11:35:48 logx.go:15: 我是fatalf日志z
github地址 https://github.com/quyixiao/go_learn.git
|