Golang理解-函数变量

函数变量


函数作为变量值

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

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

package main

// 将函数作为值保存到变量中
import (
        "fmt"
)

func fire() {
        fmt.Println("fire")
}

func main(){
        f := fire()     // 将变量f声明为func()类型,此时f就被俗称为“回调函数”, 此时f的值为nil
        f()
}

链式调用

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

  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. 链式处理的开发思想将数据和操作拆分,解耦,让开发者可以根据自己的技术优势和需求,进行系统开发,同时将自己的开发成果共享给其他的开发

原文地址:https://www.cnblogs.com/vinsent/p/11221486.html

时间: 2024-10-07 14:46:32

Golang理解-函数变量的相关文章

探究javascript对象和数组的异同,及函数变量缓存技巧

javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来存储数据有什么不同.于是,我打算探究探究. 一.掌握三种数据类型 首先,一个前提必须掌握的,就是必须理解javascript的数据类型分类,主要分为以下三种: 第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词. 第二

c 变量的存储类型auto等(基础知识)和c函数变量

总结 1).在c语言中每一个变量和函数有两个属性:数据类型和数据的存储类别. 2). 对数据型(如整型.字符型等).存储类别指的是数据在内存中存储的方式. 存储方式分为两大类: 静态存储类和动态存储类 具体包括四种:{自动的(auto), 静态的(static), 寄存器(register), 外部的(extern)}. 根据变量的存储类别, 可以知道变量的作用域和生存期. 例如: 局部变量: 自动变量: int main(void){int a, b, c; 自动变量} 静态局部变量: int

javascript 闭包与函数变量作用域

浏览器事件循环工作原理 浏览器有一个事件循环用于检查事件队列,处理延时的事件.UI事件(例如:点击,滚动等),ajax回调,以及提供给setTimeout()和setInterval()的回调,都会依次被事件循环处理. 因此,当调用setTimeout()函数时,即使延迟的时间被设置为0,提供的回调也会被排队 回调会呆在队列中,直到指定的时间用完后,引擎开始执行动作(如果它当前不执行其他动作) 因此,即使setTimeout()回调被延迟0ms,它仍然会被排队,并且直到函数中其他非延迟的语句被执

第六章 深入理解函数 Lua程序设计笔记

--第六章 深入理解函数Lua中函数是"第一类值",与其他传统类型有相同的权利:可以储存到变量或table中,可以作为函数实参传递,还可以作为函数的返回值. 函数的标准定义: foo = function(x) return x*2 end 一个函数定义实际上就是一条赋值语句,这条语句创建了一种类型为"函数"的值,并将这个值赋予一个变量. --6.1closure(闭合函数) function newCounter() local i = 0 return func

C++--模板的概念和意义、深入理解函数模板、类模板的概念和意义

一.模板的概念与意义 Q:C++中有几种交换变量的方法?定义宏代码与定义函数A.定义宏代码优点:代码复用,适合所有的类型缺点:编译器不知道宏的存在,缺少类型检查B.定义函数优点:真正的函数调用,编译器对类型进行检查缺点:根据类型重复定义函数,无法代码复用 C.泛型编程--不考虑具体数据类型的编程方式Swap泛型写法中的T不是一个具体的数据类型,而是泛指任意的数据类型C++中的泛型编程函数模板--一种特殊的函数可用不同类型进行调用,看起来和普通函数很相似,区别是类型可被参数化函数模板的语法规则1.

golang(06)函数介绍

原文链接 http://www.limerence2017.com/2019/09/11/golang11/#more 函数简介 函数是编程语言中不可缺少的部分,在golang这门语言中函数是一等公民.也是使用好golang的必备技能.看下golang函数的格式 123 func 函数名(函数参数)返回值类型{ } 一个简单的函数 123 func HelloFunc(str string) string{ return str} 该函数返回传入的字符串,函数调用如下 1 fmt.Println

2016.8.07 一个自欺欺人的代码(便于理解函数和对象)

之前在对象基础里,我说对象就像游戏里的一个人物,这个人物有血条,魔条,物理攻击力等等的基本属性,也有攻击等基本方法. 在这里,我就写一个小例子,是用来自欺欺人的.真的,随便玩玩就好,如果想认真的做一个回合制游戏,可以参考我这个代码. 不说了,直接上代码: function Person(o){ this.name= o.name; //名字 this.profession= o.profession;//职业 this.rank= o.rank; //等级 this.blood= o.blood

从缓存行出发理解volatile变量、伪共享False sharing、disruptor

volatilekeyword 当变量被某个线程A改动值之后.其他线程比方B若读取此变量的话,立马能够看到原来线程A改动后的值 注:普通变量与volatile变量的差别是volatile的特殊规则保证了新值能马上同步到主内存,以及每次使用前能够马上从内存刷新,即一个线程改动了某个变量的值,其他线程读取的话肯定能看到新的值. 普通变量: 写命中:当处理器将操作数写回到一个内存缓存的区域时.它首先会检查这个缓存的内存地址是否在缓存行中,假设不存在一个有效的缓存行,则处理器将这个操作数写回到缓存,而不

JavaScript-4.2函数,变量作用域---ShinePans

<html> <head> <meta http-equiv="content-type" content="text/html;charset=GB2312"/> <title> 4.2 函数和变量作用域 </title> <!--脚本部分--> <script type="text/javascript"> var v1,v2; v1=10; v2=20; f