zoukankan      html  css  js  c++  java
  • Go Duck Typeing & Interface & Closure

    Duck Typeing & Interface

    Duck Typing

    Duck typing in computer programming is an application of the duck test -- "if it walks like a duck and it quacks like a duck, then it must be a duck"

    Duck Typing in py

    def duck_test(duck):
        try:
            duck.quack()
            duck.walk()
        except (AttributeError, TypeError):
            print("can't quack()")
    

    Duck Typing in java

    image-20210424175638309

    Duck Typing in Go

    非侵入式 Interface

    非侵入式:不需要显示声明

    当结构体的方法是某个接口的超集的时候 就可以认为该结构体实现了某接口

    好处:降低耦合度 增加了可扩展性

    package main
    
    type person struct {
        name string
    }
    
    func (p person)sing() {
        fmt.Printf(p.name,"sing")
    }
    func (p person)dance() {
        fmt.Printf(p.name,"dance")
    }
    func (p person)rap() {
        fmt.Printf(p.name,"rap")
    }
    func (p person)playBasketball() {
        fmt.Printf(p.name,"playBasketball")
    }
    
    func (p person)playSoccer() {
        fmt.Printf(p.name,"playSoccer")
    }
    func (p person)fly() {
        fmt.Printf(p.name,"fly")
    }
    
    func show(t Trainee) {
        t.sing()
        t.dance()
        t.rap()
        t.playBasketball()
    }
    
    type Trainee interface {
        sing()
        dance()
        rap()
        playBasketball()
    }
    
    func play(p Player){
        p.playBasketball()
        p.playSoccer()
    }
    type Player interface{
        playBasketball()
        playSoccer()
    }
    
    func showOff(superman Superman){
        superman.fly()
    }
    
    type Flyer interface {
        fly()
    }
    // 组合接口
    type Superman interface {
        Flyer
        Trainee
    }
    
    func main() {
        joey := person("joey")
        show(joey)
        play(joey)
        showOff(joey)
    }
    

    Memory Allocation and Escape Analysis

    Go内存分配与逃逸分析

    堆栈内存

    • 堆Heap
      • 可以动态分配内存大小,适合不可预知大小的内存分配
      • 声明周期享有自主控制权
      • 复杂的内存管理会占用资源 速度慢 存在内存碎片已经内存泄露问题
    • 栈Stack
      • 存取数据要比堆快很多
      • 缺乏灵活性 栈中数据大小与编译器挂钩 生命周期是确定的
      • 与函数共存亡

    逃逸分析Escape Analysis

    根据堆栈数据存储不同的特点,需要对程序中的数据选择合适的区域进行存放。

    GC语言将堆栈内存的分配对于程序员变的透明。逃逸分析就是编译器能分析代码特征决定数据应该用堆还是栈来进行内存分配。

    JVM也可以通过参数开启逃逸分析

    逃逸失败案例:

    栈中变量a在函数结束的时候会被弹栈 地址空间不存在

    #include <stdio.h>
    int *returnArr(){
        int a = 3;
        return &a;
    }
    int main() {
        return 0;
    }
    

    go中编译器做的逃逸分析

    package main
    func returnArr() *int{
        a:=3
        return &a
    }
    func main() {
        
    }
    

    go build -gcflags '-m -l' main.go查看内存逃逸情况

    go tool compile -S main.go 查看局部变量是否真的进入heap中runtime.newObject(SB)

    package main
    func returnArr() *int{
        a := new(int)
        return a // new 默认返回指针
    }
    func main() {
        
    }
    

    不引发逃逸行为

    package main
    func returnArr() int{
        a := new(int) // 取决于上下文的环境 来觉得是否又必要去堆还是栈中申请内存
        // 取决于变量是否会被函数外部引用
        return *a // 不会引发逃逸行为
    }
    func main() {
        
    }
    

    go tool compile -S main.go查看发现没有去堆中申请内存的操作

    Go Closure闭包

    Closure: 关闭,倒闭,道路封闭

    闭包:

    • 函数可以作为值传递f := funcA , f := funcA()//接受返回值
    • 词法作用域,编写代码时确定的作用域,是静态的作用域。外部函数无法直接访问函数的局部变量

    函数+函数内部的引用环境

    示例:

    package main
    import "fmt"
    func enemy() func() {
        key := 0
        return func() {
            key++
            fmt.Println(key)
        }
    }
    
    func main() {
        f := enemy() // 返回匿名函数func 以及函数内部的引用环境 key
        f() // 1
        f() // 2
        f() // 3
        f() // 4
    }
    

    Function Currying(函数柯里化)

    • 分阶段接受参数
    • 参数的复用 分阶段执行
    package main
    
    func adder(a, b int) {
        fmt.Println(a + b)
    }
    
    func curryAdder(a int) func(int) {
        return func(b int) {
            fmt.Println(a + b)
        }
    }
    func main() {
        adder(1, 2) // 一次执行到位 a + b
        addB := curryAdder(1) // =>  1 + b, b还没有传入参数
        fmt.Println("wait")
        addB(2) // => 1 + 2
        addB(3) // => 1 + 3, 1被复用
    }
    

    闭包存在内存泄露的风险 谨慎使用

  • 相关阅读:
    pyinstaller 将 python 代码打包成执行文件
    python excel 处理 xlrd & xlwt &xlutils
    服务器重启后 Nvidia 环境错误
    py 编译so
    cv 读取宽高和画框
    libreOffice doc 转pdf
    gunicorn 使用
    asp.net 跬步篇(4) EnableSessionState设置 引起的框架集加载问题
    驱驾ViewState利剑—压缩ViewState
    asp.net 开发 跬步篇〔3〕.net 邮件批量发送
  • 原文地址:https://www.cnblogs.com/DengSchoo/p/14698255.html
Copyright © 2011-2022 走看看