Golang 高阶函数
定义
高阶函数是接收函数作为参数或返回函数作为输出的函数。
高阶函数是对其他函数进行操作的函数,要么将它们作为参数,要么返回它们。
举例
函数作为参数
package main
import "fmt"
func sum(x, y int) int {
return x + y
}
func process(x int, y int, f func(int, int) int) int {
return f(x, y)
}
func main() {
x, y := 1, 2
fmt.Println(process(x, y, sum))
}
输出结果
3
函数作为返回值
package main
import "fmt"
func addPrefix(str string) string {
return "prefix_" + str
}
func addSuffix(str string) string {
return str + "_suffix"
}
func process(idx int) func(string) string {
switch idx {
case 1:
return addPrefix
case 2:
return addSuffix
default:
return addPrefix
}
}
func main() {
need_prefix := []string{"aaa", "bbb", "ccc"}
need_suffix := []string{"AAA", "BBB", "CCC"}
prefix_f := process(1)
suffix_f := process(2)
for i, v := range need_prefix {
need_prefix[i] = prefix_f(v)
}
for i, v := range need_suffix {
need_suffix[i] = suffix_f(v)
}
fmt.Println("need_prefix:", need_prefix)
fmt.Println("need_suffix:", need_suffix)
}
输出结果
need_prefix: [prefix_aaa prefix_bbb prefix_ccc]
need_suffix: [AAA_suffix BBB_suffix CCC_suffix]
两者结合起来
衣服,交通工具,水果分类
定义一个结构体
type Commodity struct {
Name string
Type string
}
type Cds []*Commodity
自定义结构体的String()
先看一下没有自定义结构体的String(),打印出来的结果
[0xc0000ba000 0xc0000ba020 0xc0000ba040 0xc0000ba060 0xc0000ba080 0xc0000ba0a0]
map[clothes:[] fruit:[] others:[] transportation:[]]
map[clothes:[0xc0000ba080 0xc0000ba0a0] fruit:[0xc0000ba000 0xc0000ba020] others:[] transportation:[0xc0000ba040 0xc0000ba060]]
all fruit: [0xc0000ba000 0xc0000ba020]
全都是地址,所以我们需要实现自定义结构体的String()
func (cd *Commodity) String() string {
return cd.Type + "," + cd.Name
}
func (cds Cds) String() string {
var result string
for _, v := range cds {
// result = append(result, v.String()...)
result += v.String() + " | "
}
return result
}
再看下打印结果,顺眼多了
fruit,apple | fruit,banana | transportation,car | transportation,bike | clothes,T-shirt | clothes,skirt |
map[clothes: fruit: others: transportation:]
map[clothes:clothes,T-shirt | clothes,skirt | fruit:fruit,apple | fruit,banana | others: transportation:transportation,car | transportation,bike | ]
all fruit: fruit,apple | fruit,banana |
定一个函数,参数是用来处理每一个结构体函数,这样可以省去我们多次的for遍历
func (cds Cds) process(f func(cd *Commodity)) {
for _, v := range cds {
f(v)
}
}
正常情况下我们的输入是一串没有区分类别的数据,这种情况下我们肯定是需要去做分类的,所以我们定义个自动分类的函数
func classifier(types []string) (func(cd *Commodity), map[string]Cds) {
result := make(map[string]Cds)
for _, v := range types {
result[v] = make(Cds, 0)
}
result["others"] = make(Cds, 0)
appender := func(cd *Commodity) {
if _, ok := result[cd.Type]; ok {
result[cd.Type] = append(result[cd.Type], cd)
} else {
result["others"] = append(result["others"], cd)
}
}
return appender, result
}
除了分类后,我们有时候可能需要在一大堆未分类的数据中找到我们需要的某一种类型,所以我们还需要定义一个查找函数
func (cds Cds) findType(f func(cd *Commodity) bool) Cds {
result := make(Cds, 0)
cds.process(func(c *Commodity) {
if f(c) {
result = append(result, c)
}
})
return result
}
完整代码
package main
import "fmt"
type Commodity struct {
Name string
Type string
}
type Cds []*Commodity
func (cd *Commodity) String() string {
return cd.Type + "," + cd.Name
}
func (cds Cds) String() string {
var result string
for _, v := range cds {
// result = append(result, v.String()...)
result += v.String() + " | "
}
return result
}
func main() {
fruit1 := Commodity{"apple", "fruit"}
fruit2 := Commodity{"banana", "fruit"}
transportation1 := Commodity{"car", "transportation"}
transportation2 := Commodity{"bike", "transportation"}
clothes1 := Commodity{"T-shirt", "clothes"}
clothes2 := Commodity{"skirt", "clothes"}
all_commodity := Cds([]*Commodity{&fruit1, &fruit2,
&transportation1, &transportation2,
&clothes1, &clothes2})
fmt.Println(all_commodity)
types := []string{"fruit", "transportation", "clothes"}
appender, cds := classifier(types)
fmt.Println(cds)
all_commodity.process(appender)
fmt.Println(cds)
all_fruit := all_commodity.findType(func(cd *Commodity) bool {
return cd.Type == "fruit"
})
fmt.Println("all fruit:", all_fruit)
}
func (cds Cds) process(f func(cd *Commodity)) {
for _, v := range cds {
f(v)
}
}
func (cds Cds) findType(f func(cd *Commodity) bool) Cds {
result := make(Cds, 0)
cds.process(func(c *Commodity) {
if f(c) {
result = append(result, c)
}
})
return result
}
func classifier(types []string) (func(cd *Commodity), map[string]Cds) {
result := make(map[string]Cds)
for _, v := range types {
result[v] = make(Cds, 0)
}
result["others"] = make(Cds, 0)
appender := func(cd *Commodity) {
if _, ok := result[cd.Type]; ok {
result[cd.Type] = append(result[cd.Type], cd)
} else {
result["others"] = append(result["others"], cd)
}
}
return appender, result
}
输出结果
fruit,apple | fruit,banana | transportation,car | transportation,bike | clothes,T-shirt | clothes,skirt |
map[clothes: fruit: others: transportation:]
map[clothes:clothes,T-shirt | clothes,skirt | fruit:fruit,apple | fruit,banana | others: transportation:transportation,car | transportation,bike | ]
all fruit: fruit,apple | fruit,banana |
Golang 高阶函数的更多相关文章
- c#语言-高阶函数
介绍 如果说函数是程序中的基本模块,代码段,那高阶函数就是函数的高阶(级)版本,其基本定义如下: 函数自身接受一个或多个函数作为输入. 函数自身能输出一个函数,即函数生产函数. 满足其中一个条件就可以 ...
- swift 的高阶函数的使用代码
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- JavaScript高阶函数
所谓高阶函数(higher-order function) 就是操作函数的函数,它接收一个或多个函数作为参数,并返回一个新函数. 下面的例子接收两个函数f()和g(),并返回一个新的函数用以计算f(g ...
- python--函数式编程 (高阶函数(map , reduce ,filter,sorted),匿名函数(lambda))
1.1函数式编程 面向过程编程:我们通过把大段代码拆成函数,通过一层一层的函数,可以把复杂的任务分解成简单的任务,这种一步一步的分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...
- python学习道路(day4note)(函数,形参实参位置参数匿名参数,匿名函数,高阶函数,镶嵌函数)
1.函数 2种编程方法 关键词面向对象:华山派 --->> 类----->class面向过程:少林派 -->> 过程--->def 函数式编程:逍遥派 --> ...
- Scala的函数,高阶函数,隐式转换
1.介绍 2.函数值复制给变量 3.案例 在前面的博客中,可以看到这个案例,关于函数的讲解的位置,缺省. 4.简单的匿名函数 5.将函数做为参数传递给另一个函数 6.函数作为输出值 7.类型推断 8. ...
- Python之路 day3 高阶函数
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:ersa """ 变量可以指向函数,函数的参数能接收变量, 那么 ...
- JavaScript高阶函数 map reduce filter sort
本文是笔者在看廖雪峰老师JavaScript教程时的个人总结 高阶函数 一个函数就接收另一个函数作为参数,这种函数就称之为高阶函数 1.高阶函数之map: ...
- js高阶函数
我是一个对js还不是很精通的选手: 关于高阶函数详细的解释 一个高阶函数需要满足的条件(任选其一即可) 1:函数可以作为参数被传递 2:函数可以作为返回值输出 吧函数作为参数传递,这代表我们可以抽离一 ...
随机推荐
- python 函数基础知识
1.函数返回的多个值会被组织成元组被返回,也可以用多个值来接收 2.调用函数时候,传入的参数叫实际参数,简称实参,定义函数的参数叫做形式参数,简称形参-- 位置参数 def mymax(x,y): a ...
- 使用 JDBC 操作数据库时,如何提升读取数据的性能?如 何提升更新数据的性能?
要提升读取数据的性能,可以指定通过结果集(ResultSet)对象的 setFetchSize() 方法指定每次抓取的记录数(典型的空间换时间策略):要提升更新数据的性能 可以使用 PreparedS ...
- SQLyog创建数据库过程
点击数据库,点击创建数据库 输入数据库名称,输入字符集,排序规则选默认的 然后一个数据库就建好了
- HTML5摇一摇(上)—如何判断设备摇动
刚刚过去的一年里基于微信的H5营销可谓是十分火爆,通过转发朋友圈带来的病毒式传播效果相信大家都不太陌生吧,刚好最近农历新年将至,我就拿一个"摇签"的小例子来谈一谈HTML5中如何调 ...
- 用Node处理文件上传
前言 在Web开发中,文件上传是一个非常常见.非常重要的功能.本文将介绍如何用Node处理上传的文件. 需求分析 由于现在前后端分离很流行,那么本文也直接采用前后端分离的做法.前端界面如下: 用户从浏 ...
- C#编写一个计算器
编写一个计算器,练习在窗体上添加控件.调整控件的布局,设置或修改控件属性,编写事件处理程序的方法. 代码: using System; using System.Collections.Generic ...
- Docker 核心知识回顾
Docker 核心知识回顾 最近公司为了提高项目治理能力.提升开发效率,将之前的CICD项目扩展成devops进行项目管理.开发人员需要对自己的负责的项目进行流水线的部署,包括写Dockerfile ...
- Wireshark捕获网易云音乐音频文件地址
打开Wireshark,开始捕获. 打开网易云音乐,然后播放一首歌. Wireshark停时捕获,然后在不活的文件中搜索字符串"mp3".可以发现有如下信息: 将其中的内容:&qu ...
- [源码解析] TensorFlow 分布式环境(8) --- 通信机制
[源码解析] TensorFlow 分布式环境(8) --- 通信机制 目录 [源码解析] TensorFlow 分布式环境(8) --- 通信机制 1. 机制 1.1 消息标识符 1.1.1 定义 ...
- SpringBoot-总结
SpringBoot一站式开发 官网:https://spring.io/projects/spring-boot Spring Boot可以轻松创建独立的.基于Spring的生产级应用程序,它可以让 ...