flag 中的 Go 函数指针

栏目: C · 发布时间: 5年前

内容简介:在阅读 flag 包的代码时,看到一处对函数指针的精妙用法。在这里想和大家分享一下。废话不多说,我们直接上代码。如果上面的代码不清楚含义,请阅读之前讲解 flag 包的文章。

在阅读 flag 包的代码时,看到一处对函数指针的精妙用法。在这里想和大家分享一下。

引出问题

废话不多说,我们直接上代码。

var CommandLine = NewFlagSet(os.Args[0], ExitOnError)

func init() {
	CommandLine.Usage = commandLineUsage
}

func commandLineUsage() {
	Usage()
}

var Usage = func() {
	fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
	PrintDefaults()
}

如果上面的代码不清楚含义,请阅读之前讲解 flag 包的文章。

咋一看还真不知道,干了些啥,更不明白为什么要将 Usage() 包一层。

那我们先来看一下下面这段代码。尝试运行一下。删除上面一条语句的注释并注释下面一条语句,再运行一下并对比不同。

package main

import "fmt"

type printer struct {
	print func()
}

var p = &printer{}

var printA = func() {
	println("A")
}

func wrapper() {
	printA()
	fmt.Printf("wrapper printA %p, &printA %p\n", printA, &printA)
}

func init() {
	// p.print = printA
	p.print = wrapper
}

func printB() {
	println("B")
}

func main() {
	fmt.Printf("printA  %p, &printA  %p\n", printA, &printA)
	fmt.Printf("printB  %p\n", printB)
	fmt.Printf("p.print %p, &p.print %p\n", p.print, &p.print)
	fmt.Printf("wrapper %p\n", wrapper)

	printA()
	fmt.Printf("printA  %p, &printA  %p\n", printA, &printA)
	p.print()
	fmt.Printf("p.print %p, &p.print %p\n", p.print, &p.print)

	printA = printB
	printA()
	fmt.Printf("printA  %p, &printA  %p\n", printA, &printA)
	p.print()
	fmt.Printf("p.print %p, &p.print %p\n", p.print, &p.print)
}

现在我们好好对比一下两者到不同。

带有包装

带有包装时的输出如下:

printA  0x1093490, &printA  0x115fd78       # here
printB  0x1092fa0
p.print 0x1092e80, &p.print 0x11666c8
wrapper 0x1092e80                           # here
A
printA  0x1093490, &printA  0x115fd78       # here
A
wrapper printA 0x1093490, &printA 0x115fd78 # here
p.print 0x1092e80, &p.print 0x11666c8
B
printA  0x1092fa0, &printA  0x115fd78       # here
B
wrapper printA 0x1092fa0, &printA 0x115fd78 # here
p.print 0x1092e80, &p.print 0x11666c8

修改 printA 前,printA 变量的地址为 0x115fd78,printA 中所存当函数地址为 0x1093490。

修改 printA 后,printA 中所存当函数地址变成 0x1092fa0。wrapper 中 printA 发生同样当变化。

所以可以得出,wrapper 中所存的是 printA 变量的地址。

flag 中的  <a href='https://www.codercto.com/topics/6127.html'>Go</a>  函数指针

不带包装

不带包装时的输出如下:

printA  0x1093480, &printA  0x115fd78 # here
printB  0x1092f90
p.print 0x1093480, &p.print 0x11666c8 # here
wrapper 0x1092e80
A
printA  0x1093480, &printA  0x115fd78 # here
A
p.print 0x1093480, &p.print 0x11666c8 # here
B
printA  0x1092f90, &printA  0x115fd78 # here
A
p.print 0x1093480, &p.print 0x11666c8 # here

由输出可以得出,p.print 中的存是函数当地址。这也符合 “=” 的本意。将 printA 中的值赋给 p.print。

flag 中的 Go 函数指针

作业

讲了这么多,那关于 flag 包中的代码片段就留给大家自己思考了。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大数据经济

大数据经济

谢文 / 北京联合出版公司·后浪出版公司 / 2016-1 / 32.00元

中国互联网数朝元老、中国的“凯文·凯利”首度深度剖析大数据的大机会 大数据纳入中国国家行动方略,大数据产业起飞在即 陈彤、胡舒立、王巍鼎力推荐 ................... ※编辑推荐※ ★ 雅虎中国前总裁、中国互联网第一预言家——谢文,首部大数据力作。本书作者是中国互联网业第一代创业者,历任和讯网总裁、雅虎中国总裁、一起网CEO,亲身经历中国互联网发展全过......一起来看看 《大数据经济》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具