文档章节

Go函数值 && 方法值

秋风醉了
 秋风醉了
发布于 2016/07/11 19:25
字数 649
阅读 48
收藏 0

Go函数值 && 方法值

函数值

在Go中,函数被看作第一类值(first-class values):函数像其他值一样,拥有类型,可以被赋值给其他变量,传递给函数,从函数返回。例子如下:

package main

import (
	"fmt"
)

func main() {
	f := square       //把 square 赋值给 f
	fmt.Println(f(3)) // "9"

	f = negative
	fmt.Println(f(3))     // "-3"
	fmt.Printf("%T\n", f) // f 的类型是 "func(int) int"

	// 类型不同,无法赋值
	// f = product // cannot use product (type func(int, int) int) as type func(int) int in assignment

	var ff func(int) int
	if ff != nil { //函数的值 可以和 nil 比较 ,但是函数值之间是不可比较的,也不能用函数值作为map的key。
		ff(3)
	}

	fff := sum(1, 2)
	res := fff(2)

	fmt.Println(res)        // 6
	fmt.Printf("%T\n", fff) // func(int) int

	res2 := sum(1, 2)(2) // 可以这样链式调用,函数 sum 是一个高阶函数
	fmt.Println(res2)    // 6

	////////////////函数作为参数////////////////
	var f1 func(int) int //声明一个函数类型的变量
	//初始化
	f1 = func(a int) int {
		return a * 2
	}

	res3 := sumF(f1)(4, 5) // 链式调用
	fmt.Println(res3)      // 18

	// sumF 的类型
	fmt.Printf("%T\n", sumF) // func(func(int) int) func(int, int) int
}

func square(n int) int     { return n * n }
func negative(n int) int   { return -n }
func product(m, n int) int { return m * n }

// 函数作为返回值

// go 不允许函数嵌套,可以使用把匿名函数赋值给一个变量
func sum(a, b int) func(int) int {

	x := a + b

	temp := func(factor int) (res int) {
		return x * factor
	}

	return temp
}

// 函数作为参数
func sumF(f func(int) int) func(int, int) int {
	return func(a, b int) int {
		if a > b {
			return 0
		} else {
			return f(a + b)
		}
	}
}

方法值和方法表达式

https://docs.ruanjiadeng.com/gopl-zh/ch6/ch6-04.html

这块比较绕,对照着程序运行结果也可以猜个差不多。

package main

import (
	"fmt"
	"math"
)

func main() {

	p := Point{1, 2}
	q := Point{4, 6}

	/*
	   distanceFromP
	   scaleP
	   都是方法值
	*/

	// p.Distance叫作“选择器”,选择器会返回一个方法"值"
	distanceFromP := p.Distance   // method value
	fmt.Println(distanceFromP(q)) // "5"

	var origin Point                   // {0, 0}
	fmt.Println(distanceFromP(origin)) // "2.23606797749979"

	scaleP := p.ScaleBy // method value
	scaleP(2)           // p becomes (2, 4)

	fmt.Println(p)

	fmt.Println(distanceFromP(origin)) // "2.23606797749979"
	fmt.Println(p.Distance(origin))    // "4.47213595499958"

	fmt.Printf("%T\n", distanceFromP) //方法的类型:func(main.Point) float64
	fmt.Printf("%T\n", scaleP)        //方法的类型:func(float64)

	////////////////////////////////
	////  方法表达式
	////////////////////////////////
	distance := Point.Distance // method expression
	fmt.Println(distance(p, q))
	fmt.Printf("%T\n", distance) // "func(Point, Point) float64"

	scale := (*Point).ScaleBy
	scale(&p, 2)
	fmt.Println(p)
	fmt.Printf("%T\n", scale) // "func(*Point, float64)"
}

type Point struct{ X, Y float64 }

// same thing, but as a method of the Point type
func (p Point) Distance(q Point) float64 {
	return math.Hypot(q.X-p.X, q.Y-p.Y)
}

// 指针对象的方法
// 这个方法的名字是(*Point).ScaleBy。这里的括号是必须的;没有括号的话这个表达式可能会被理解为*(Point.ScaleBy)。
func (p *Point) ScaleBy(factor float64) {
	p.X *= factor
	p.Y *= factor
}

======END======

© 著作权归作者所有

共有 人打赏支持
秋风醉了
粉丝 232
博文 575
码字总数 406007
作品 0
朝阳
程序员
【翻译】Go 1.1 函数调用

Go 1.0 版本的 runtime 使用动态代码生成来实现闭包。我认为这样一点也不方便:它避免了修改工具链宽来表达函数的值与函数调用惯例。然而,自从它限制了 Go 可以运行的环境,这就很明显地警示...

无闻
2013/08/02
0
11
NSGA2代码分析——dominance.c

该源文件中包含一个函数int check_dominance (individual *a, individual *b), 主要功能是比较两个个体的支配关系,该函数有三个返回值:0——两个体不可比较支配关系;1——a个体支配b;-...

长平狐
2012/09/20
115
0
为什么 (obj.foo)() 调用的执行环境中的 this 就是 obj ?

首先,看一段代码: var obj = {foo: function() { }} 用不同的方式调用obj的foo方法有不同的结果: obj.foo(); // this is obj !(obj.foo)(); // this is obj !(0 || obj.foo)(); // this ......

呵呵闯
2016/08/14
19
0
JQuery属性与样式——.att()和.removeAttr()

1 每个元素都有一个或多个特性,用途是给出相应元素或者其内容的附加信息,如:在img元素中,src就是元素的特性,用来标记图片的地址 2 操作特性的主要DOM方法 getAttribute方法 setAttribu...

拉考的考拉
2017/11/13
0
0
jQuery批量修改Name值,批量增加name后缀,非each(不需要循环)

背景 表单字段,配置where属性自动刷新到可查询区域,查询字段需增加_where后缀,响应后台规则 问题 批量设置的查询字段,必须批量增加_where后缀方可正常查询。each循环有点麻烦,有没有更方...

沫沫金
2017/09/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

go语言学习总结

一、描述 go语言是直接将源码编译成二进制机器码的语言;它支持面向对象、也支持函数式编程;支持并发很容易; 二、基本语法学习路径 https://studygolang.com/subject/2...

盼望明天
17分钟前
1
0
JSP 九大内置对象及其作用域

JSP 中一共预先定义了 9 个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception ,下面就简单介绍下。 1、request 对象 request 对象...

几个栗子
28分钟前
0
0
Java中的坑之方括号

Java中的坑之方括号 这一段时间,在做项目的时候,发现了一个坑,这个坑说大不大,说小不小,不知道的足够喝一壶,知道的就可以轻松解决。 问题描述 在做数据统计的时候,遇见了如下形式的数...

星汉
38分钟前
1
0
[雪峰磁针石博客]python机器学习、web开发等书籍汇总

Building Machine Learning Systems with Python Third Edition - 2018.pdf 下载地址 Get more from your data by creating practical machine learning systems with Python Key Features ......

python测试开发人工智能安全
49分钟前
1
0
文件的压缩与解压(linux)

Linux下*.tar.gz文件解压缩命令 1.压缩命令:   命令格式:tar -zcvf 压缩后文件名.tar.gz 被压缩文件名 可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。 2.解压缩命令: ...

qimh
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部