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")
}
原文地址:https://www.cnblogs.com/GYoungBean/p/13777838.html