Go语言是使用包来组织源代码的,包(package)是多个 Go 源码的集合,是一种高级的代码复用方案。
包可以定义在很深的目录中,包名的定义是不包括目录路径的,但是包在引用时一般使用全路径引用。比如在GOPATH/src/a/b/ 下定义一个包 c。在包 c 的源码中只需声明为package c,而不是声明为package a/b/c,但是在导入 c 包时,需要带上路径,例如import “a/b/c”。
包的习惯用法:
包中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 = 1
func main() {
m.Add(100, 200)
stu := m.Student{
Name: "haojie", Age: 18}
fmt.Println(stu.Name)
fmt.Println(stu.Age)
}
导入包:
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 main
import (
"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 200612345
func 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()
}
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 main
import "fmt"
// 接口实现一个洗衣机
// 只要一个类型它实现了 wash() 和 dry() 方法,我们就称这个类型实现了xiyiji这个接口
type xiyiji interface {
wash()
dry()
}
type Haier struct {
name string
price float64
mode 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类型的变量a
h1 := Haier{
// 实例化了一个Haier结构体对象
name: "小神童",
price: 998.98,
mode: "滚筒",
}
fmt.Printf("%T\n", h1)
a = h1 // 接口是一种类型,一种抽象的类型。
fmt.Println(a)
tl := tianluo{
name: "螺蛳粉",
}
a = tl
fmt.Println(a)
}
空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此,我们可以说所有类型都至少实现了空接口。
type empty_iface interface {
}
package main
import (
"fmt"
)
func main() {
var i interface{
}
fmt.Printf("type: %T, value: %v", i, i)
}
类型断言
package main
import "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 main
import (
"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 File
fmt.Println("文件已经读完了")
return
}
if err != nil {
fmt.Println("read from file failed, err:", err)
return
}
fmt.Printf("读取了%d个字节\n", n)
fmt.Println(string(tmp[:]))
}
}
package main
import (
"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()
// ioutil
readFile("../12file_open/xx.txt")
}
package main
import (
"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/O
O_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件
)