From 1c4077795fb853dcc5838344e3c116ab91fd9434 Mon Sep 17 00:00:00 2001 From: SisMaker <1713699517@qq.com> Date: Fri, 10 Jul 2020 12:51:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/goPanicRecover.md | 28 ++++++++++++++++++ src/docs/go闭包讲解.md | 13 +++++++++ src/learn/Closure/Closure.go | 21 ++++++++++++++ src/learn/Closure/Closure1.go | 30 ++++++++++++++++++++ src/learn/Closure/funn.go | 21 ++++++++++++++ src/learn/calcQ.go | 53 +++++++++++++++++++++++++++++++++++ 6 files changed, 166 insertions(+) create mode 100644 src/docs/goPanicRecover.md create mode 100644 src/docs/go闭包讲解.md create mode 100644 src/learn/Closure/Closure.go create mode 100644 src/learn/Closure/Closure1.go create mode 100644 src/learn/Closure/funn.go create mode 100644 src/learn/calcQ.go diff --git a/src/docs/goPanicRecover.md b/src/docs/goPanicRecover.md new file mode 100644 index 0000000..231f4fd --- /dev/null +++ b/src/docs/goPanicRecover.md @@ -0,0 +1,28 @@ +# 作用 + pacin用来主动抛出错误 + recover用来捕捉panic抛出的错误 + +# 基本概念 + 函数签名 + panic(i interface) + recover() interface{} + + 引发panic有两种情况 一种是程序主动调用panic函数,另外一种就是程序产生运行时的错误,由运行是检测并抛出 + + 发生panic后 程序会从调用panic的函数位置或发生panic的地方立即返回, 逐层向上执行函数的defer语句, + 然后逐层打印函数调用堆栈, 直到被recover捕获或运行到最外层函数而退出 + + panic的参数是个空的接口类型interface{} 所以任意类型的变量都可以传参给panic + panic 不但可以在函数正常流程中抛出, 在defer逻辑里也可以再次调用panic或抛出panic + defer里面的panic能够被后续执行的defer捕获 + recover()用来捕获panic,阻止panic继续向上传递, recover()和defer一起使用,但是recover() + 只有在defer后面的函数体内被直接调用才能捕获panic终止异常, 否则返回nil, 异常继续向外传递 + + + + + + + + + \ No newline at end of file diff --git a/src/docs/go闭包讲解.md b/src/docs/go闭包讲解.md new file mode 100644 index 0000000..1826b83 --- /dev/null +++ b/src/docs/go闭包讲解.md @@ -0,0 +1,13 @@ +# 闭包 + 概念: 闭包是由函数及其引用环境组合而成,一般通过在匿名函数中引用外部函数的局部变量或全局变量构成 + 所以: 闭包=函数 + 引用环境 + 闭包对闭包外的环境引入是直接引用,编译器检测到闭包,会将闭包使用的外部变量分配到堆上 + 如果函数返回的闭包使用了该函数的局部变量(参数或函数内部变量): + 1. 多次调用该函数,返回的多个闭包所引用的外部变量是多个副本, 原因是每次调用函数都会为局部变量分配内存 + 2. 用一个闭包函数多次, 如果该闭包修改了其使用的外部变量, 则每一次调用改闭包对该外部变量都有影响,因为闭包函数共享外部引用 + + 如果一个函数调用返回的闭包使用全局变量,则每次调用都会影响全局变量 + 如果函数返回的闭包引用的是全局变量a,则多次调用该函数返回的多个闭包引用的都是同一个a, 同理调用一个闭包多次用的也是同一个a,此时如果闭包 + 中修改了a值的逻辑则每次闭包调用都会影响全局变量a的值, 使用闭包的目的是为了减少全局变量,所以闭包引用全局变量不是好的编程方式。 + 同一个函数返回的多个闭包共享该函数的局部变量 + \ No newline at end of file diff --git a/src/learn/Closure/Closure.go b/src/learn/Closure/Closure.go new file mode 100644 index 0000000..ba2abd1 --- /dev/null +++ b/src/learn/Closure/Closure.go @@ -0,0 +1,21 @@ +package main + +func fa(a int) func(i int) int { + return func(i int) int { + println(&a, a) + a = a + i + return a + } +} +func main() { + f := fa(1) // f引用的外部闭包环境包括本次函数调用的形参a的值1 + g := fa(1) // g引用的外部闭包环境包括本次函数调用的形参a的值1 + // 此时 f, g 引用的闭包环境中的a的值 并不是同一个 而是两次函数调用产生的副本 + + println(f(10)) + println(f(10)) + + println(g(10)) + println(g(10)) + +} diff --git a/src/learn/Closure/Closure1.go b/src/learn/Closure/Closure1.go new file mode 100644 index 0000000..31afce1 --- /dev/null +++ b/src/learn/Closure/Closure1.go @@ -0,0 +1,30 @@ +package main + +func fa(base int) (func(int) int, func(int) int) { + println(&base, base) + add := func(i int) int { + println("adddddddd") + base -= i + println(&base, base) + return base + } + + sub := func(i int) int { + println("subbbbbbbb") + base -= i + println(&base, base) + return base + } + return add, sub + +} + +func main() { + // f, g闭包引用的base是同一个, 是fa函数调用传递过来的实参值 + f, g := fa(0) + + println(f(1), g(2)) + + s, k := fa(0) + println(s(1), k(2)) +} diff --git a/src/learn/Closure/funn.go b/src/learn/Closure/funn.go new file mode 100644 index 0000000..2ee449e --- /dev/null +++ b/src/learn/Closure/funn.go @@ -0,0 +1,21 @@ +package main + +func main() { + f := func() interface{} { + println("inner 00000000") + return func() { + println("inner 11111111111") + + } + //println("inner 222222222") + }() + d := f.(func()) + d() + test(test("111111111", "2222222222"), test("333333333", "444444444444")) +} + +func test(a string, b string) string { + + println("testttt", a, b) + return a +} diff --git a/src/learn/calcQ.go b/src/learn/calcQ.go new file mode 100644 index 0000000..e1e4053 --- /dev/null +++ b/src/learn/calcQ.go @@ -0,0 +1,53 @@ +package main + +import ( + "fmt" + "math" + "math/rand" +) + +func calcQuality(min, max, equipQuality, continueMatNumb int32, jewelQualityMap map[int32]int32) int32 { + base := make(map[int32]float32) + for i := min; i <= max; i++ { + if i == equipQuality { + base[i] = float32(jewelQualityMap[i]) + float32(continueMatNumb) + } else { + base[i] = float32(jewelQualityMap[i]) + } + } + var reduce float32 = 0.5 + var sum float32 = 0 + var sumWeight float32 = 0.0 + tem := make(map[int32]float32) + for i := min; i <= max; i++ { + sum += base[i] + tem[i] = sum * float32(max-i) * reduce + sumWeight += base[i] + tem[i] + base[i] = base[i] + tem[i] + } + randRatio := rand.Float32() * sumWeight + var temRation float32 = 0.0 + fmt.Printf("allllll :%v\n", sumWeight) + for i := min; i <= max; i++ { + fmt.Printf("oneeeee : %v %v ** %v \n", i, base[i], base[i]/sumWeight) + } + + for i := min; i <= max; i++ { + temRation += base[i] + if randRatio < temRation { + return i + } + } + return min +} + +func CeilToInt32(v float32) int32 { + return int32(math.Ceil(float64(v))) +} + +func main() { + q := calcQuality(1, 4, 2, 4, map[int32]int32{1: 1, 3: 1, 4: 1}) + fmt.Printf("get eeeeeeeeeee %v", q) + lastCost := CeilToInt32(float32(500 * 100.0 / (100 + 1))) + println("IMY********************", lastCost) +}