• Go学习笔记2


    继续记录一下go课程的练习demo

    ch7 Map

    package my_map
    
    import "testing"
    
    func TestInitMap(t *testing.T) {
    	m1 := map[int]int{1: 1, 2: 4, 3: 9}
    	t.Log(m1[2])
    	t.Logf("len m1=%d", len(m1))
    
    	m2 := map[int]int{}
    	m2[4] = 16
    	t.Logf("len m2=%d", len(m2))
    
    	m3 := make(map[int]int, 10)
    	t.Logf("len m3=%d", len(m3))
    }
    
    /**
    map初始化时候,获取值时候 取到不存在key时返回0
    在访问的 Key 不存在时,仍会返回零值,不能通过返回 nil 来判断元素是否存在
    */
    func TestAccess(t *testing.T) {
    	m1 := map[int]int{}
    	//返回0
    	t.Log(m1[1])
    
    	m1[2] = 0
    	t.Log(m1[2])
    	//怎么区分是没有key还是值为0
    	//使用if的返回值,返回的两个参数,第一个参数为值,第二个boolean值
    	m1[3]=0
    	if v, ok := m1[3]; ok {
    		t.Logf("Key 3 value is %d", v)
    	} else {
    		t.Log("key 3 is not existing")
    	}
    }
    
    /**
    map遍历 使用range
    */
    func TestTravelMap(t *testing.T) {
    	m1 := map[int]int{1: 1, 2: 4, 3: 9}
    	for k,v:=range m1{
    		t.Log(k,v)
    	}
    }
    
    

    ch8 Map扩展

    package map_ext_test
    
    import "testing"
    
    /**
    用函数作为value值
     */
    func TestMapWithFunValue(t *testing.T) {
    	m := map[int]func(op int) int{}
    	m[1] = func(op int) int { return op }
    	m[2] = func(op int) int { return op * op }
    	m[3] = func(op int) int { return op * op * op }
    	t.Log(m[1](2), m[2](2), m[3](2))
    }
    
    /**
    Go 的内置集合中没有 Set 实现, 可以 map[type]bool
     */
    func TestMapForSet(t *testing.T) {
    	mySet:= map[int]bool{}
    	mySet[1] = true
    	n:=1
    	if mySet[n]{
    		t.Logf("%d is extising",n)
    	}else {
    		t.Logf("%d is not extising",n)
    	}
    	mySet[3]=true
    	t.Log(len(mySet))
    	delete(mySet,1)
    	if mySet[n]{
    		t.Logf("%d is extising",n)
    	}else {
    		t.Logf("%d is not extising",n)
    	}
    }
    

    ch9 字符串string操作

    package string_test
    
    import (
    	"strconv"
    	"strings"
    	"testing"
    )
    
    func TestStringFn(t *testing.T) {
    	s := "A,B,C"
    	parts := strings.Split(s, ",")
    	for _, part := range parts {
    		t.Log(part)
    	}
    	t.Log(strings.Join(parts,"-"))
    }
    
    func TestStringConv(t *testing.T) {
    	s:=strconv.Itoa(10)
    	//转字符串
    	t.Log("str"+s)
    	//字符串转整型
    	if i,err:=strconv.Atoi("10");err==nil{
    		t.Log(10+i)
    	}
    
    }
    
    package string_test
    
    import "testing"
    /**
    字符串常用包
     */
    func TestString(t *testing.T){
    	var s string
    	t.Log(s)
    	s = "hello"
    	t.Log(len(s))
    	s="xE4xB8xA5"
    	t.Log(s)
    	s="中"
    	t.Log(len(s))
    	/**
    	rune(取出字符串的uincode)
    	 */
    	c:=[]rune(s)
    	t.Logf("中 unicode %x",c[0])
    	//e4b8ad
    	t.Logf("中 UTF8 %x",s)
    
    }
    
    func TestStringToRune(t *testing.T) {
    	s:="中华人民共和国"
    	for _,c:=range s{
    		//以百分号c格式化 以百分号d格式化,[1]标识匹配第一个参数 可以用来遍历字符集
    		t.Logf("%[1]c %1[1]x",c)
    	}
    }
    

    ch10 函数

    package fn_test
    
    import (
    	"fmt"
    	"math/rand"
    	"reflect"
    	"strconv"
    	"testing"
    	"time"
    )
    
    func returnMultiValues() (int, int) {
    	return rand.Intn(10), rand.Intn(20)
    }
    
    /*
    返回一个函数运行的时长
    */
    func timeSpent(inner func(op int) int) func(op int) int {
    	ret := func(n int) int {
    		start := time.Now()
    		ret := inner(n)
    		fmt.Println("time spent:", time.Since(start).Seconds())
    		return ret
    	}
    	return ret
    }
    
    func slowFun(op int) int {
    	time.Sleep(time.Second * 1)
    	return op
    }
    
    func fastFun(op int) int {
    	a := strconv.Itoa(op) + "10"
    	//字符串转整型
    	var b int
    	if i, err := strconv.Atoi(a); err == nil {
    		b = i
    	}
    	return b
    }
    
    func Clear() {
    	fmt.Println("Clear resources.")
    }
    
    /**
    defer 延迟函数,相当于finally
    */
    func TestDefer(t *testing.T) {
    	//
    	defer Clear()
    	fmt.Println("Start")
    	//跑出异常,panic执行后defer仍会执行
    	panic("err")
    }
    
    //函数的可变参数
    func Sum(ops ...int) int {
    	ret := 0;
    	for _, op := range ops {
    		ret += op
    	}
    	return ret
    }
    
    func TestVarParma(t *testing.T){
    	t.Log(Sum(1,2,3,5))
    	t.Log(Sum(1,2,3,4))
    }
    
    func TestFn(t *testing.T) {
    	//只获取一个返回值,使用下划线忽略一个返回值
    	//a, _ := returnMultiValues()
    	//t.Log(a)
    
    	//获取2个返回值
    	//a, b := returnMultiValues()
    	//t.Log(a, b)
    
    	tsSF := timeSpent(slowFun)
    	t.Log("----------", reflect.TypeOf(tsSF))
    	t.Log(tsSF(10))
    	//tsFF := timeSpent(fastFun)
    	//t.Log("----------")
    	//t.Log(tsFF(20))
    }
    
    

    ch11 接口、方法、自定义类型

    接口

    package interface_test
    
    import "testing"
    
    /**
    Go接口
    1. 接⼝为⾮⼊侵性,实现不依赖于接口定义
    2. 所以接⼝的定义可以包含在接口使⽤者包内
     */
    type Programmer interface {
    	WriteHelloWorld() string
    }
    
    type GoProgrammer struct {
    }
    /**
    Duck Type式接口方式
    接口签名一致,就是响应的方法
     */
    func (go1 *GoProgrammer) WriteHelloWorld() string  {
    	return "Hello World"
    }
    //测试接口
    func TestClient(t *testing.T)  {
    	var p Programmer
    	p = new(GoProgrammer)
    	t.Log(p.WriteHelloWorld())
    
    
    	//接口变量
    	var prog Programmer = &GoProgrammer{}
    	/**
    	prog 类型为:
    		type GoProgrammer struct{}
    	prog的数据为:
    		&GoProgrammer{}
    	 */
    	t.Log(prog.WriteHelloWorld())
    }
    
    

    行为 方法

    package encapsulation_test
    
    import (
    	"fmt"
    	"testing"
    	"unsafe"
    )
    
    /**
    结构体定义
    */
    type Employee struct {
    	id   string
    	name string
    	age  int
    }
    
    func TestEncap(t *testing.T) {
    	e := Employee{"aaa", "AAA", 1}
    	e1 := Employee{id: "bbb", name: "BBB", age: 2}
    	//注意这⾥返回的引⽤/指针,相当于 e := &Employee{}
    	e2 := new(Employee)
    	//与其他主要编程语⾔的差异:通过实例的指针访问成员不需要使⽤->
    	e2.id = "ccc"
    	e2.name = "CCC"
    	e2.age = 3
    
    	t.Log(e)
    	t.Log(e1)
    	t.Log(e1.id)
    	t.Log(e2)
    	t.Log(e2.id)
    	//输出类型
    	t.Logf("e is %T", e)
    	t.Logf("e is %T", &e)
    	t.Logf("e is %T", e2)
    }
    
    /*
    行为(方法)定义
    */
    
    //第⼀种定义⽅式在实例对应⽅法被调⽤时,实例的成员会进⾏值复制
    func (e Employee) String() string {
    	//获取地址 地址值不一致
    	fmt.Printf("Address is %x
    ",unsafe.Pointer(&e.name))
    	return fmt.Sprintf("ID:%s-Name%s-Age:%d", e.id, e.name, e.age)
    }
    
    //通常情况下为了避免内存拷⻉我们使⽤第⼆种定义⽅式
    //func (e *Employee) String() string  {
    //	//获取地址 地址值一致
    //	fmt.Printf("Address is %x",unsafe.Pointer(&e.name))
    //	return fmt.Sprintf("ID:%s/Name%s/Age:%d",e.id,e.name,e.age)
    //}
    
    func TestStructOperations(t *testing.T) {
    	e := Employee{"0", "AAA", 1}
    	//获取地址
    	fmt.Printf("Address is %x
    ",unsafe.Pointer(&e.name))
    	//调用方法
    	t.Log(e.String())
    
    
    	//e1 := &Employee{"0", "AAA", 1}
    	//类型指针实例,调用其成员或者方法时不需要使用箭头函数,直接使用"."
    	//t.Log(e1.String())
    }
    
    

    自定义类型

    package customer_type_test
    
    import (
    	"fmt"
    	"testing"
    	"time"
    )
    
    /**
    自定义类型
    创建一个自定义的类型
    */
    type IntConv func(op int) int
    
    /*
    返回一个函数运行的时长
    */
    func timeSpent(inner IntConv) IntConv {
    	ret := func(n int) int {
    		start := time.Now()
    		ret := inner(n)
    		fmt.Println("time spent:", time.Since(start).Seconds())
    		return ret
    	}
    	return ret
    }
    
    func slowFun(op int) int {
    	time.Sleep(time.Second * 1)
    	return op
    }
    
    func TestFn(t *testing.T) {
    	tsSF := timeSpent(slowFun)
    	t.Log(tsSF(10))
    }
    
    

    ch12 扩展与复合

    package extension
    
    import (
    	"fmt"
    	"testing"
    )
    
    type Pet struct {
    }
    
    func (p *Pet) Speak() {
    	fmt.Println("...")
    }
    func (p *Pet) SpeakTo(name string) {
    	p.Speak()//这里会调用自己的Speak方法,不会调用dog的speak方法
    	fmt.Println("",name)
    }
    
    /**
    扩展Pet功能为例
     */
    type Dog struct {
    	p *Pet
    }
    
    //在父类中不会调用子类的speak方法
    //func (aDog *Dog) Speak() {
    //	fmt.Println("Wang!!!")
    //	aDog.p.Speak()
    //}
    //在父类中不会调用子类的speak方法
    //func (aDog *Dog) SpeakTo(name string) {
    //	aDog.p.SpeakTo(name)
    //}
    
    
    //这里和java不同
    //子类自己实现speak方法
    func (aDog *Dog) Speak() {
    	fmt.Println("Wang!!!")
    }
    //子类自己实现speak方法
    func (aDog *Dog) SpeakTo(name string) {
    	aDog.Speak()
    	fmt.Println("",name)
    }
    
    
    func TestDog(t *testing.T) {
    	dog:= new(Dog)
    	dog.SpeakTo("Chao")
    }
    
    package extension
    
    import (
    	"fmt"
    	"testing"
    )
    
    type Pet1 struct {
    }
    
    func (p *Pet1) Speak() {
    	fmt.Println("...")
    }
    func (p *Pet1) SpeakTo(name string) {
    	p.Speak() //这里会调用自己的Speak方法,不会调用dog的speak方法
    	fmt.Println("", name)
    }
    
    /**
    扩展Pet功能为例
    go 中提供了一种匿名嵌套类型的声明
    并没有重载方法
    内嵌的结构类型不支持重载
    */
    type Dog1 struct {
    	Pet1
    }
    
    //在父类中不会调用子类的speak方法
    //func (aDog *Dog) Speak() {
    //	fmt.Println("Wang!!!")
    //	aDog.p.Speak()
    //}
    //在父类中不会调用子类的speak方法
    //func (aDog *Dog) SpeakTo(name string) {
    //	aDog.p.SpeakTo(name)
    //}
    
    //子类自己实现speak方法
    func (aDog *Dog1) Speak() {
    	fmt.Println("Wang!!!")
    }
    
    func TestDog1(t *testing.T) {
    	//匿名嵌套类型的调用
    	dog := new(Dog1)
    	dog.SpeakTo("Chao")
    
    	/**
    	以下声明会报错,Go不支持显示类型转换的
    	Go中无法支持LSP的原则
    	 */
    	//var dog1 Pet1 = new(Dog1)
    	//dog1.SpeakTo("Chao")
    }
    

    ch13 多态 空接口 断言

    多态

    package polymorphism
    
    import (
    	"fmt"
    	"testing"
    )
    
    /**
    GO的多态
    */
    type Code string
    type Programmer interface {
    	WriteHelloWorld() Code
    }
    
    type GoProgrammer struct {
    }
    
    func (p *GoProgrammer) WriteHelloWorld() Code {
    	return "fmt.Println("Hello World")"
    }
    
    type JavaProgrammer struct {
    }
    
    func (p *JavaProgrammer) WriteHelloWorld() Code {
    	return "fmt.Println("Hello World")"
    }
    
    //%T 输出实例类型
    func wirteFirstProgram(p Programmer) {
    	fmt.Printf("%T %v
    ", p, p.WriteHelloWorld())
    }
    
    func TestPolymorphism(t *testing.T) {
    	//Programmer是一个接口,只能对应一个指针实例,实例化时也可以
    	//goProg:=&GoProgrammer{}
    	//但不可以goProg:=GoProgrammer{}
    	goProg := new(GoProgrammer)
    
    	javaProg := new(JavaProgrammer)
    	wirteFirstProgram(goProg)
    	wirteFirstProgram(javaProg)
    }
    

    空接口 断言

    package empty_interface
    
    import (
    	"fmt"
    	"testing"
    )
    
    /**
    空接口 断言
     */
    func DoSomthing(p interface{}) {
    	//if i,ok:=p.(int);ok{
    	//	fmt.Println("Integer",i)
    	//	return
    	//}
    	//
    	//if s,ok:=p.(string);ok{
    	//	fmt.Println("String",s)
    	//	return
    	//}
    	//fmt.Println("Unknow Type")
    
    	//使用swtich
    	switch v:=p.(type) {
    	case int:
    		fmt.Println("Integer",v)
    	case string:
    		fmt.Println("String",v)
    	default:
    		fmt.Println("Unknow Type")
    	}
    }
    
    func TestEmptyInterfaceAssertion(t *testing.T) {
    	DoSomthing(10)
    	DoSomthing("10")
    }
    
  • 相关阅读:
    细说VMWare加入OpenStack
    云计算和大数据的崛起
    HTML5 Web app开发工具Kendo UI Web教程:如何配置Kendo UI Calendar
    Android:增强目录选择器对话框
    Gartner指明2014年几大战略技术趋势
    Android开发人员终于在“app-构建控制台”中获得分析
    谷歌升级Android分析应用程序
    Android是Windows开发人员可选择的下一个平台
    Greek
    为什么质数有无穷多个
  • 原文地址:https://www.cnblogs.com/GYoungBean/p/13777838.html
Copyright © 2020-2023  润新知