zoukankan      html  css  js  c++  java
  • Golang理解-函数变量

    函数变量


    函数作为变量值

    函数变量是把函数作为值保存到变量中.

    在Golang中,,函数也是一种类型,可以和其他类型一样被保存在变量中.例如:

    package main
    
    // 将函数作为值保存到变量中
    import (
    		"fmt"
    )
    
    func fire() {
    		fmt.Println("fire")
    }
    
    func main(){
    		f := fire() 	// 将变量f声明为func()类型,此时f就被俗称为“回调函数”, 此时f的值为nil
    		f()
    }
    

    我们经常选择一个方法,并且在同一个表达式里执行,比如常见的p.Distance()形式,实际上将其分成两步来执行也是可能的。
    p.Distance叫作“选择器”,选择器会返回一个方法"值"->一个将方法(Point.Distance)绑定到特定接收器变量的函数。
    这个函数可以不通过指定其接收器即可被调用;即调用时不需要指定接收器(译注:因为已经在前文中指定过了),只要传入函数的参数即可:

    p := Point{1, 2}
    q := Point{4, 6}
    
    distanceFromP := p.Distance        // method value
    fmt.Println(distanceFromP(q))
    

    当你根据一个变量来决定调用同一个类型的哪个函数时,方法表达式就显得很有用了。你可以根据选择来调用接收器各不相同的方法。
    下面的例子,变量op代表Point类型的addition或者subtraction方法,Path.TranslateBy方法会为其Path数组中的每一个Point来调用对应的方法

    package main
    
    import "fmt"
    
    type Point struct {
        X, Y float64
    }
    
    func (p Point) Add(q Point) Point {
        return Point{
            X: p.X + q.X,
            Y: p.Y + q.Y,
        }
    }
    
    func (p Point) Sub(q Point) Point {
        return Point{p.X - q.X, p.Y - q.Y}
    }
    
    type Path []Point
    
    func (p Path) TranslateBy(offset Point, add bool) Path {
        var opration func(q, p Point) Point
    
        if add {
            opration = Point.Add
        } else {
            opration = Point.Sub
        }
    
        for i := range p {
            p[i] = opration(p[i], offset)
        }
    
        return p
    }
    
    
    func main() {
        // p := Point{1,1}
        q := Point{2,2}
        path := Path{{1,1}, {2,2}, {3,3}}
    
        fmt.Printf("%#v
    ", path.TranslateBy(q, true))
    }
    

    链式调用

    链式调用是一个泛概念,到底是什么东西的链式调用不明确。

    1. 函数的返回值是一个函数时,函数也能链式调用;

    2. 函数的返回值是一个对象时,直接调用返回值中对象的方法也是链式调用。

    但是前者(1)显然是没有意义的。真正有意义的链式调用是后者(2),也就是方法链(method chaining)。方法链这个词是有的,而且使用的很广泛。其实很多人口中的链式调用实际上就是指方法链。但是链式调用这个词语还可以描述函数调用链,所以让它自身的存在价值变得难以理解。

    链式调用的优点:

    1. 让调用过程更接近自然语言。
    2. 把原本参数列表复杂的方法化作多个参数列表简单的方法来使用。
    3. 减少不必要的代码量。

    上面引用至

    在jQuery中很多东西就是使用了方法链的概念,那么在Golang中链式调用是怎么样的呢?

    实例 :字符串的链式处理

    链式调用很好的体现了: 操作与数据分离的设计

    字符串处理函数(StringProccess)需要外部提供数据源: 一个字符串切片(list []string), 另外还需要提供一个链式处理函数的切片(chain []func(string) string)

    字符串链式处理设计思路:

    1. 这种处理函数能够接受一个字符串输入,处理后输出
    2. strings.ToLower()函数能够将传入的字符串的每个字符变为小写 func ToLower(s string) string
    3. 字符串处理函数StringProccess内部遍历每个数据源提供的字符串,每个字符串都要经过一系列链式处理后重新返回切片
    package main
    
    import (
    	"fmt"
    	"strings"
    )
    
    
    //  StringProccess 字符串处理函数,传入字符串切片和处理链
    func StringProccess(list []string, chain []func(string) string) {
        // 遍历每一个字符串
        for index, str := range list {
          // 第一个需要处理的字符串
          result := str
          // 遍历每一个处理链
          for _, proc := range chain {
            // 输入一个字符串进行处理,返回数据作为下一个处理链的输入
            result = proc(result)
          }
          // 将结果放回切片
          list[index] = result
        }
    }
    
    // 自定义处理函数
    // 处理链函数即可以是系统提供的处理函数,也可以使用自定义的函数
    // 自定义移除前缀的处理函数
    func removePrefix(str string) string {
    		return strings.TrimPrefix(str, "go")
    }
    
    func main() {
        // 提供待处理的字符串列表
        list := []string{
          "go scanner",
          "go parser",
          "go compiler",
          "go printer",
          "go formater",
        }
    
        // 处理函数链
        chain := []func(string) string {
          removePrefix,
          strings.TrimSpace,
          strings.ToUpper,
        }
    
        // 处理字符串
        StringProccess(list, chain)
    
        // 输出处理好的字符串
        for _, str := range list {
          fmt.Printf(str)
        }
    }
    

    总结


    1. 链式处理器是一种常见的编程设计.Netty是使用java语言编写的一款异步事件驱动的网络应用程序框架,
      支持快速开发可维护的高性能的面向协议的服务器和客户端,Netty中就有类似的链式处理器的设计.
    2. 链式处理的开发思想将数据和操作拆分,解耦,让开发者可以根据自己的技术优势和需求,进行系统开发,同时将自己的开发成果共享给其他的开发
  • 相关阅读:
    Python-zip压缩-解压
    使用zabbix监控nginx
    原已经安装好的nginx,现在需要添加一个未被编译安装的模块:
    zabbix 邮件告警配置
    lnmp-zabbix
    Mysql新建用户和数据库并授权
    git标签管理
    Ubuntu下安装tomcat
    git分支管理
    Java拦截器
  • 原文地址:https://www.cnblogs.com/vinsent/p/11221486.html
Copyright © 2011-2022 走看看