194. go学习3

从下往上看

package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

type Monkey struct {
	Name string
}

type BirdAble interface {
	Flaying()
}

type FishAble interface {
	Swimming()
}

func (this *Monkey) climbing() {
	fmt.Println(this.Name, "会爬树...")
}

type LittleMonkey struct {
	Monkey
}

func (this *LittleMonkey) Flaying() {
	fmt.Println(this.Name, "学会了飞翔")
}

func (this *LittleMonkey) Swimming() {
	fmt.Println(this.Name, "学会了游泳")

}

func test1() {
	/*
		对上面代码的小结
		1) 当 A 结构体继承了 B 结构体,那么 A 结构就自动的继承了 B 结构体的字段和方法,并且可以直接使用
		2) 当 A 结构体需要扩展功能,同时不希望去破坏继承关系,则可以去实现某个接口即可,因此我们可以认为:实现接口是对继承机制的补充.
		实现接口可以看作是对 继承的一种补充

		继承是被动的, 接口是主动的.
		继承被动继承了父类结构体字段和方法; 而接口可以主动扩展某些功能
	*/
	monkey := LittleMonkey{
		Monkey{Name: "悟空"},
	}
	monkey.climbing()
	monkey.Flaying()
	monkey.Swimming()
}

type Usb interface {
	Start()
	Stop()
}

type Phone struct {
	name string
}

func (this Phone) Start() {
	fmt.Println(this.name, "start working")
}

func (this Phone) Stop() {
	fmt.Println(this.name, "Stop working")
}

func (this Phone) Call() {
	fmt.Println(this.name, "phone can call")
}

type Camera struct {
	name string
}

func (this Camera) Start() {
	fmt.Println(this.name, "start working")
}

func (this Camera) Stop() {
	fmt.Println(this.name, "Stop working")
}

func test2() {
	var usbArr []Usb
	var phone Phone = Phone{name: "apple"}
	var camera Camera = Camera{name: "索尼"}
	usbArr = append(usbArr, phone, camera)
	for _, val := range usbArr {
		val.Start()
		if p1, ok := val.(Phone); ok {
			p1.Call()
		}
		val.Stop()
	}
}

type Point struct {
	x int
	y int
}

func test3() {
	var a interface{}
	var point Point = Point{1, 2}
	a = point // ok
	var b Point
	// b = a // error
	b, ok := a.(Point) // 一个空接口可以赋值任何对象, 但是当空接口对象要赋值给其他对象是需要转换
	if !ok {
		fmt.Println("转换失败")
		return
	}
	fmt.Println(b)

	var x interface{}
	var b2 float32 = 1.1
	x = b2
	y, ok := x.(float32)
	if !ok { // 练习给test2中Phone添加call方法, 当类型为Phoen时指向Call方法
		fmt.Println("转换失败")
		return
	}
	fmt.Printf("y 的类型是%T, 值是%v", y, y)
}

func TypeJudge(items ...interface{}) {
	for index, x := range items {
		switch x.(type) {
		case bool:
			fmt.Printf("第%v个参数%v, type 是 bool类型
", index, x)
		case float32:
			fmt.Printf("第%v个参数%v, type 是 float32类型
", index, x)
		case float64:
			fmt.Printf("第%v个参数%v, type 是 float64类型
", index, x)
		case int, int32, int64:
			fmt.Printf("第%v个参数%v, type 是 int, int32, int64类型
", index, x)
		case string:
			fmt.Printf("第%v个参数%v, type 是string类型
", index, x)
		case Student:
			fmt.Printf("第%v个参数%v, type 是Student类型
", index, x)
		case *Student:
			fmt.Printf("第%v个参数%v, type 是*Student类型
", index, x)
		default:
			fmt.Printf("第%v个参数%v,类型不确定
", index, x)
		}
	}
}

type Student struct {
	Name string
}

func test4() {
	var n1 float32 = 1.1
	var n2 float64 = 1.1
	var n3 int = 30
	var n4 string = "fadsf"
	n5 := 1000

	var s1 Student = Student{Name: "alex"}
	var s2 *Student = &Student{Name: "alex"}
	TypeJudge(n1, n2, n3, n4, n5, s1, s2)
}

type AccountRecord struct {
	Title   string
	Income  float32
	Desc    string
	Balance float32
}

type Account struct {
	TotalAmount float32
	Records     []*AccountRecord
	Loop        bool
	Key         string
}

func test5() {
	account := Account{}
	account.Records = append(account.Records, &AccountRecord{})
	fmt.Println(account.Key, account.TotalAmount, account.Records, account.Loop)
}

//TODO go 韩顺平 360-379项目2没做
func test6() {
	filename := "C:/Users/yzt/Desktop/gitlab初始化使用.txt"
	file, err := os.Open(filename)
	defer file.Close()
	if err != nil {
		fmt.Println("文件打开失败, err: ", err)
	}
	// const (
	// 	defaultBufSize = 4096
	// )

	// 创建一个reader对象,读取文件
	reader := bufio.NewReader(file)
	for {
		str, err := reader.ReadString('
')
		if err == io.EOF {
			break
		}
		fmt.Print(str)
	}

	fmt.Println("file=%v", file)
	err = file.Close()
	if err != nil {
		fmt.Println("关闭文件失败, err: ", err)
	}
}

func test7() {
	// ioutil不适合大文件
	filename := "C:/Users/yzt/Desktop/gitlab初始化使用.txt"
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println("文件打开失败, err: ", err)
	}
	fmt.Printf("%v", string(content))
}

func test8() {
	filename := "C:/Users/yzt/Desktop/test.txt"
	file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println("文件打开失败, err: ", err)
		return
	}
	defer file.Close()
	str := "hello, Gardon
"
	writer := bufio.NewWriter(file)
	for i := 0; i < 5; i++ {
		writer.WriteString(str)
	}
	writer.Flush()
}

func test9() {
	filename := "C:/Users/yzt/Desktop/test.txt"
	file, err := os.OpenFile(filename, os.O_WRONLY|os.O_TRUNC, 0666)
	if err != nil {
		fmt.Println("文件打开失败, err: ", err)
		return
	}
	defer file.Close()
	str := "你好, 尚硅谷
"
	writer := bufio.NewWriter(file)
	for i := 0; i < 5; i++ {
		writer.WriteString(str)
	}
	writer.Flush()
}

func test10() {
	filename := "C:/Users/yzt/Desktop/test.txt"
	file, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println("文件打开失败, err: ", err)
		return
	}
	defer file.Close()
	str := "1233333333
"
	//写入时,使用带缓存的 *Writer
	writer := bufio.NewWriter(file)
	for i := 0; i < 5; i++ {
		writer.WriteString(str)

	}
	//因为 writer 是带缓存,因此在调用 WriterString 方法时,其实
	//内容是先写入到缓存的,所以需要调用 Flush 方法,将缓冲的数据
	//真正写入到文件中, 否则文件中会没有数据!!!
	writer.Flush()
}

func test11() {
	filename := "C:/Users/yzt/Desktop/test.txt"
	file, err := os.OpenFile(filename, os.O_APPEND|os.O_RDWR, 0666)
	if err != nil {
		fmt.Println("文件打开失败, err: ", err)
		return
	}
	defer file.Close()

	reader := bufio.NewReader(file)
	for {
		str, err := reader.ReadString('
')
		if err == io.EOF {
			break
		}
		fmt.Print(str)
	}

	str := "尚硅谷!尚硅谷!尚硅谷!
"
	//写入时,使用带缓存的 *Writer
	writer := bufio.NewWriter(file)
	for i := 0; i < 5; i++ {
		writer.WriteString(str)

	}
	//因为 writer 是带缓存,因此在调用 WriterString 方法时,其实
	//内容是先写入到缓存的,所以需要调用 Flush 方法,将缓冲的数据
	//真正写入到文件中, 否则文件中会没有数据!!!
	writer.Flush()
}

func test12() {
	filename1 := "C:/Users/yzt/Desktop/test.txt"
	filename2 := "C:/Users/yzt/Desktop/gitlab初始化使用.txt"

	content, err := ioutil.ReadFile(filename2)
	if err != nil {
		fmt.Println("read file err: ", err)
		return
	}

	// WriteFile会先将文件清空之后,在写入
	err = ioutil.WriteFile(filename1, []byte(content), 0666)
	if err != nil {
		fmt.Println("writer file err: ", err)
		return
	}
}

func PathExists(path string) (isExists bool, err error) {
	_, err = os.Stat(path)
	if err == nil {
		isExists = true
		return
	}
	if os.IsNotExist(err) {
		return
	}
	return
}

func test13() {
	filename := "C:/Users/yzt/Desktop/test.txt"
	flag, err := PathExists(filename)
	if err != nil {
		fmt.Println("文件不存在")
	}
	if flag {
		fmt.Println("文件存在")
	}
}

func CopyFile(dest string, src string) (written int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		fmt.Println("opne file err: ", err)
		return
	}
	defer srcFile.Close()

	reader := bufio.NewReader(srcFile)

	dstFile, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println("opne file err: ", err)
		return
	}

	writer := bufio.NewWriter(dstFile)
	defer dstFile.Close()
	written, err = io.Copy(writer, reader)
	return
}

func test14() {
	// copy图片
	pngname := "C:/Users/yzt/Pictures/timg3.jpg"
	pngname2 := "C:/Users/yzt/Pictures/timg2.jpg"
	_, err := CopyFile(pngname2, pngname)
	if err != nil {
		fmt.Println("copy 文件失败")
	}
}

type CharCount struct {
	ch int
	nm int
	sc int
	oc int
}

func test15() {
	filename1 := "C:/Users/yzt/Desktop/test.txt"
	file, err := os.Open(filename1)
	if err != nil {
		fmt.Println("open file err:", err)
		return
	}

	defer file.Close()
	var count CharCount
	reader := bufio.NewReader(file)

	for {
		str, err := reader.ReadString('
')
		if err == io.EOF {
			break
		}
		str2 := []rune(str)
		for _, v := range str2 {
			switch {
			case v >= 'a' && v <= 'z':
				fallthrough
			case 'A' <= v && v <= 'Z':
				count.ch++
			case v == ' ' || v == '	':
				count.sc++
			case '0' <= v && v <= '9':
				count.nm++
			default:
				count.oc++
			}
		}
	}
	fmt.Printf("字符的个数为=%v 数字的个数为=%v 空格的个数为=%v 其它字符个数=%v",
		count.ch, count.nm, count.sc, count.oc)
}

func test16(args []string) {
	/*
		// 首个参数是当前文件路径, 之后为执行时后面接的参数
		PS F:go_dev> go run day01/example1 1 2 3
		命令行的参数有 4
		C:UsersyztAppDataLocalTempgo-build1572730542001exeexample1.exe
		1
		2
		3
	*/
	for _, v := range args {
		fmt.Println(v)
	}
}

func test17() {
	var user string
	var pwd string
	var host string
	var port int

	/*
		PS F:go_dev> go run day01/example1 -u alex -p 123456
		命令行的参数有 5
		alex 123456 localhost 3306
	*/

	flag.StringVar(&user, "u", "", "用户名, 默认为空")
	flag.StringVar(&pwd, "p", "", "密码, 默认为空")
	flag.StringVar(&host, "h", "localhost", "主机名, 默认为localhost")
	flag.IntVar(&port, "port", 3306, "端口号默认为3306")
	flag.Parse()
	fmt.Println(user, pwd, host, port)
}

type Monster struct {
	Name     string  `json:"name"`
	Age      int     `json:"age"`
	Birthday string  `json:"birthday"`
	Sal      float64 `json:"slary"`
	Skill    string  `json:"slill"`
}

func test18() {
	// 序列化对象
	moster := Monster{
		Name:     "牛魔王",
		Age:      500,
		Birthday: "2011-11-11",
		Sal:      8000.0,
		Skill:    "牛崽子",
	}

	data, err := json.Marshal(&moster)
	if err != nil {
		fmt.Println("json序列化struct失败: err", err)
		return
	}
	fmt.Println(string(data))

	// 序列化字典
	var a map[string]interface{}
	a = make(map[string]interface{})
	a["name"] = "红孩儿"
	a["age"] = 30
	a["address"] = "洪崖洞"
	data, err = json.Marshal(&a)
	if err != nil {
		fmt.Println("json序列化map失败: err", err)
		return
	}
	fmt.Println(string(data))

	// 序列化切片
	var slice []map[string]interface{}
	var m1 map[string]interface{}
	m1 = make(map[string]interface{})
	m1["name"] = "红孩儿"
	m1["age"] = 30
	m1["address"] = "洪崖洞"

	slice = append(slice, m1)

	var m2 map[string]interface{}
	m2 = make(map[string]interface{})
	m2["name"] = "八戒"
	m2["age"] = 3000
	m2["address"] = "高老庄"

	slice = append(slice, m2)

	data, err = json.Marshal(&slice)
	if err != nil {
		fmt.Println("json序列化slice失败: err", err)
		return
	}
	fmt.Println(string(data))

	var num1 float32 = 2345.67
	data, err = json.Marshal(&num1)
	if err != nil {
		fmt.Println("json序列化float32失败: err", err)
		return
	}
	fmt.Println(string(data))
}

func test19() {
	// 反序列化struct
	str := "{"Name":"牛魔王","Age":500,"Birthday":"2011-11-11","Sal":8000,"Skill":"牛魔拳"}"
	var monster Monster
	err := json.Unmarshal([]byte(str), &monster)
	if err != nil {
		fmt.Println("反序列化struct失败: err", err)
		return
	}
	fmt.Println(monster, monster.Name)

	// 反序列换map
	str = "{"address":"洪崖洞","age":30,"name":"红孩儿"}"
	var a map[string]interface{}
	err = json.Unmarshal([]byte(str), &a)
	if err != nil {
		fmt.Println("反序列化map失败: err", err)
		return
	}
	fmt.Println(a, a["address"])

	// 反序列化slice
	str = "[{"address":"北京","age":"7","name":"jack"}," +
		"{"address":["墨西哥","夏威夷"],"age":"20","name":"tom"}]"

	var slice []map[string]interface{}
	err = json.Unmarshal([]byte(str), &slice)
	if err != nil {
		fmt.Println("反序列化slice失败: err", err)
		return
	}
	fmt.Println(slice, slice[0])
	/*
		对上面代码的小结说明
		1) 在反序列化一个json字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。
		2) 如果 json 字符串是通过程序获取到的,则不需要再对 “ 转义处理。
	*/
}

func main() {
	// test1() // 接口和继承
	// test2() // 多态
	// test3() // 类型断言
	// test4() // 类型断言
	// test5()
	// test6() //文件操作os.File
	// test7() // ioutil
	// test8() // os.OpenFile 写入数据
	// test9()  // 打开一个存在的文件, 覆盖其中的数据
	// test10() // 打开一个存在的文件, 向其中追加数据
	// test11() // 打开一个存在的文件, 将其中内容输出控制台, 之后向其中追加数据
	// test12() // 编程一个程序,将一个文件的内容,写入到另外一个文件。注:这两个文件已经存在了
	// test13() // 判断文件是否存在
	// test14() // 文件拷贝
	// test15() // 统计英文、数字、空格和其他字符数量
	fmt.Println("命令行的参数有", len(os.Args))
	// test16(os.Args) // 命令行参数
	// test17() // flag包解析命令行参数
	test18() // json序列化
	test19() // json反序列化
}
原文地址:https://www.cnblogs.com/liuzhanghao/p/15352760.html