包
Go语言是使用包来组织源代码的,包(package)是多个 Go 源码的集合,是一种高级的代码复用方案。
包可以定义在很深的目录中,包名的定义是不包括目录路径的,但是包在引用时一般使用全路径引用。比如在GOPATH/src/a/b/ 下定义一个包 c。在包 c 的源码中只需声明为package c,而不是声明为package a/b/c,但是在导入 c 包时,需要带上路径,例如import “a/b/c”。
包的习惯用法:
- 包名一般是小写的,使用一个简短且有意义的名称。
- 包名一般要和所在的目录同名,也可以不同,包名中不能包含- 等特殊符号。
- 包一般使用域名作为目录名称,这样能保证包名的唯一性,比如 GitHub 项目的包一般会放到GOPATH/src/github.com/userName/projectName 目录下。
- 包名为 main 的包为应用程序的入口包,编译不包含 main 包的源码文件时不会得到可执行文件。
- 一个文件夹下的所有源码文件只能属于同一个包,同样属于同一个包的源码文件不能放在多个文件夹下。
包中Init函数的执行时机:
包的导入顺序:
package main// 这个文件是干什么的import "fmt"// 导入包时起别名import m "code.oldboy.com/studygolang/day04/02package/math_pkg"// import (// "fmt"// "code.oldboy.com/studygolang/day04/02package/math_pkg"// )const Mode = 1func main() {m.Add(100, 200)stu := m.Student{Name: "haojie", Age: 18}fmt.Println(stu.Name)fmt.Println(stu.Age)}
time包
导入包:
import ("fmt""time")
当前时间戳
time.Now().Unix()
str格式化时间
time.Now().Format("2006-01-02 15:04:05")
时间戳转str格式化时间
str_time := time.Unix(1389058332, 0).Format("2006-01-02 15:04:05")
示例:
package mainimport ("fmt""time")// 内置的time包func timestamp2Timeobj(timestamp int64) {timeObj := time.Unix(timestamp, 0) //将时间戳转为时间格式fmt.Println(timeObj)year := timeObj.Year() //年month := timeObj.Month() //月day := timeObj.Day() //日hour := timeObj.Hour() //小时minute := timeObj.Minute() //分钟second := timeObj.Second() //秒fmt.Printf("%4d-%02d-%02d %02d:%02d:%02d\\n", year, month, day, hour, minute, second)}func tickDemo() {ticker := time.Tick(time.Second) //定义一个1秒间隔的定时器for i := range ticker {fmt.Println(i) //每秒都会执行的任务// f1()}}// yyyy- m-d// 2006-01-02 15:04:05 200612345func formatDemo() {now := time.Now()// 格式化的模板为Go的出生时间2006年1月2号15点04分fmt.Println(now.Format("2006-01-02 15:04:05.000"))fmt.Println(now.Format("2006/01/02 15:04"))fmt.Println(now.Format("15:04 2006/01/02"))fmt.Println(now.Format("2006/01/02"))}func main() {// time.Time struct// now := time.Now()// fmt.Printf("%#v\\n", now)// fmt.Println(now.Year())// fmt.Println(now.Month())// fmt.Println(now.Day())// fmt.Println(now.Hour())// fmt.Println(now.Minute())// fmt.Println(now.Second())// fmt.Println(now.Nanosecond())// // 时间戳// fmt.Println(now.Unix())// fmt.Println(now.UnixNano())// tm := now.Unix()// timestamp2Timeobj(tm)// 定时器// tickDemo()// 日期格式化 时间格式的数据 ==> 字符串格式formatDemo()}
接口(interface)
Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
定义
type interface_name interface {method_name1 [return_type]method_name2 [return_type]method_name3 [return_type]...method_namen [return_type]}/* 定义结构体 */type struct_name struct {/* variables */}/* 实现接口方法 */func (struct_name_variable struct_name) method_name1() [return_type] {/* 方法实现 */}...func (struct_name_variable struct_name) method_namen() [return_type] {/* 方法实现*/}
接口实现一个洗衣机
package mainimport "fmt"// 接口实现一个洗衣机// 只要一个类型它实现了 wash() 和 dry() 方法,我们就称这个类型实现了xiyiji这个接口type xiyiji interface {wash()dry()}type Haier struct {name stringprice float64mode string}// 田螺姑娘type tianluo struct {name string}func (t tianluo) wash() {fmt.Println("田螺姑娘可以洗衣服~")}func (t tianluo) dry() {fmt.Println("田螺姑娘可以把衣服拧干~")}func (h Haier) wash() {fmt.Println("海尔洗衣机能洗衣服~")}func (h Haier) dry() {fmt.Println("海尔洗衣机自带甩干~")}func main() {var a xiyiji // 声明一个xiyijie类型的变量ah1 := Haier{ // 实例化了一个Haier结构体对象name: "小神童",price: 998.98,mode: "滚筒",}fmt.Printf("%T\\n", h1)a = h1 // 接口是一种类型,一种抽象的类型。fmt.Println(a)tl := tianluo{name: "螺蛳粉",}a = tlfmt.Println(a)}
空接口
空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此,我们可以说所有类型都至少实现了空接口。
type empty_iface interface {}
package mainimport ("fmt")func main() {var i interface{}fmt.Printf("type: %T, value: %v", i, i)}
类型断言
package mainimport "fmt"type Cat struct{}// 类型断言// type nullInterface interface {}// 太繁琐func ShowType(x interface{}) {// 因为我这个函数可以接收任意类型的变量// 类型断言v1, ok := x.(int)if !ok {// 说明猜错了fmt.Println("不是int")} else {fmt.Println("x就是一个int类型", v1)}v2, ok := x.(string)if !ok {fmt.Println("不是string")} else {fmt.Println("x是一个string类型", v2)}}// type nullInterface interface{}func justifyType(x interface{}) {switch v := x.(type) {case string:fmt.Printf("x is a string,value is %v\\n", v)case int:fmt.Printf("x is a int,value is %v\\n", v)case bool:fmt.Printf("x is a bool, value is %v\\n", v)case Cat:fmt.Printf("x is a Cat struct,value is %v\\n", v)case *string:fmt.Printf("x is a string poninter,value is %v\\n", v)default:fmt.Println("unsupport type!")}}func main() {// var x interface{}// x = 100// ShowType(100)// ShowType("哈哈")// switch版类型断言justifyType(100)justifyType(Cat{})s := "哈哈"justifyType(&s)}
文件操作
文件打开和关闭
os.Open()os.OpenFile()os.close()
package mainimport ("fmt""io""os")// 打开和关闭文件func main() {file, err := os.Open("./xx.txt")if err != nil {fmt.Println("open file failed, err:", err)return}// 文件能打开defer file.Close() // 使用defer延迟关闭文件// 读文件var tmp [128]byte //定义一个字节数组// var s = make([]byte, 0, 128)for {n, err := file.Read(tmp[:]) // 基于数组得到一个切片if err == io.EOF { // End Of Filefmt.Println("文件已经读完了")return}if err != nil {fmt.Println("read from file failed, err:", err)return}fmt.Printf("读取了%d个字节\\n", n)fmt.Println(string(tmp[:]))}}
bufio读数据
package mainimport ("bufio""fmt""io""io/ioutil""os")// bufio读数据func readByLine() {file, err := os.Open("../12file_open/xx.txt")if err != nil {fmt.Println("打开文件失败")return}defer file.Close()// 利用缓冲区从文件读数据reader := bufio.NewReader(file)for {str, err := reader.ReadString('\\n') // 字符if err == io.EOF {fmt.Print(str)return}if err != nil {fmt.Println("读取文件内容失败")return}fmt.Print(str)}}// ioutil读取文件func readFile(filename string) {content, err := ioutil.ReadFile(filename)if err != nil {fmt.Println("read file failed, err:", err)return}fmt.Println(string(content))}func main() {readByLine()// ioutilreadFile("../12file_open/xx.txt")}
文件写入
package mainimport ("fmt""os")// 打开文件支持文件写入func main() {file, err := os.OpenFile("xx.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0755)if err != nil {fmt.Println("打开文件失败", err)return}defer file.Close()str := "Hello 沙河"file.Write([]byte("哈哈哈\\n"))file.WriteString(str)}
const (O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件O_RDWR int = syscall.O_RDWR // 读写模式打开文件O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部O_CREATE int = syscall.O_CREAT // 如果不存在将创建一个新文件O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用,文件必须不存在O_SYNC int = syscall.O_SYNC // 打开文件用于同步I/OO_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件)