Go函数值 && 方法值
Go函数值 && 方法值
秋风醉了 发表于2年前
Go函数值 && 方法值
  • 发表于 2年前
  • 阅读 44
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: Go函数值 && 方法值

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======

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 216
博文 605
码字总数 432178
×
秋风醉了
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: