zoukankan      html  css  js  c++  java
  • 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反序列化
    }
    
  • 相关阅读:
    LeetCode 515. 在每个树行中找最大值(Find Largest Value in Each Tree Row)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 1022. 从根到叶的二进制数之和(Sum of Root To Leaf Binary Numbers)
    LeetCode 897. 递增顺序查找树(Increasing Order Search Tree)
    LeetCode 617. 合并二叉树(Merge Two Binary Trees)
    LeetCode 206. 反转链表(Reverse Linked List) 16
    LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)
    LeetCode 110. 平衡二叉树(Balanced Binary Tree) 15
    LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14
  • 原文地址:https://www.cnblogs.com/liuzhanghao/p/15352760.html
Copyright © 2011-2022 走看看