函数重写

huangapple go评论72阅读模式
英文:

Function override

问题

我在Go语言中发现了一些有趣的东西。假设我的包名是mypkg,在mypkg中,我有两个函数:

package mypkg

func MyFunc0(){
    //...
}

var MyFunc1 = func(){
    //...
}

现在在我的main包中,可以通过以下方式重写MyFunc1

mypkg.MyFunc1 = func(){
   // 新逻辑
}

然而,无法以同样的方式重写MyFunc0。因此,现在提出了一个问题:声明函数的这两种方式有什么区别?这种行为差异是有意为之的吗?

英文:

I found something interesting in Go. Let's say I have my package name is mypkg, inside mypkg, I have two functions:

package mypkg
func MyFunc0(){
    //...
}
var MyFunc1 = func(){
    //...
}

Now in my main package, it is possible to override MyFunc1, like this:

mypkg.MyFunc1 = func(){
   // new logic
}

However, it is not possible to override MyFunc0 the same way. So now a question is raised. What are the differences between the two ways of declaring a function? Is this behavior difference intended?

答案1

得分: 5

MyFunc0 是一个函数声明(https://golang.org/ref/spec#Function_declarations)

MyFunc1 不是一个函数声明。它是一个类型为 func 的变量(参见 https://golang.org/ref/spec#Variable_declarations)。它有一个初始值,但可以更改为保存不同的值/函数(只要函数签名匹配)。

英文:

MyFunc0 is a function declaration (https://golang.org/ref/spec#Function_declarations)

MyFunc1 is not a function declaration. It is a variable (https://golang.org/ref/spec#Variable_declarations) of type func (see https://golang.org/ref/spec#Function_types, https://golang.org/ref/spec#Function_literals). It has an initial value, but can be changed to hold a different value/function (as long as function signatures match).

答案2

得分: 0

我正在学习Go语言(和英语:P),在Go之旅中有一个练习:斐波那契闭包。

结果是:
0
1
1
2
3
5
8
13
21
34

主要函数是:

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

我的第一个解决方案是:

func fibonacci() func() int {
    antant := 0
    ant := 1
    i := 0
    return func() int {
        var result int
        if i == 0 || i == 1 {
            result = i
            i++
            return result
        }
        result = antant + ant
        antant = ant
        ant = result
        return result
    }
}

但是我不想在每次调用f()时都询问是否是第一次或第二次调用(if i == 0 || i == 1)。结果是一个函数自动覆盖:

type doFibonacci func(*doFibonacci) int

func fibonacci() func() int {
    antant := 0
    ant := 1
    i := 0
    doFibo := doFibonacci(func(ptrDo *doFibonacci) int {
        var result int
        if i == 0 || i == 1 {
            result = i
            i++
            return result
        }
        *ptrDo = func(ptrDo *doFibonacci) int {
            var result int
            result = antant + ant
            antant = ant
            ant = result
            return result
        }
        return (*ptrDo)(ptrDo)
    })
    return func() int {
        return doFibo(&doFibo)
    }
}

对于我的英语我表示歉意。

英文:

I learning go language (and English :P), and in the tour of go is a exersie: Fibonacci closure

(https://tour.golang.org/moretypes/22)

The result is:
0
1
1
2
3
5
8
13
21
34

The main function is:

func main() {
	f := fibonacci()
	for i := 0; i &lt; 10; i++ {
		fmt.Println(f())
	}
}

And my first solution was:

func fibonacci() func() int {
    antant := 0
    ant := 1
    i := 0
    return func() int {
        var result int
        if i == 0 || i == 1 {
            result = i
            i++
            return result
        }
        result = antant + ant
        antant = ant
        ant = result
        return result
    }
}

But I didn't want ask in heach call to f() if was the firsth or second call (if i == 0 || i == 1). The result was a function auto-override:

type doFibonacci func(*doFibonacci) int

func fibonacci() func() int {
	antant := 0
	ant := 1
	i := 0
	doFibo := doFibonacci(func(ptrDo *doFibonacci) int {
		var result int
		if i == 0 || i == 1 {
			result = i
			i++
			return result
		}
		*ptrDo = func(ptrDo *doFibonacci) int {
			var result int
			result = antant + ant
			antant = ant
			ant = result
			return result
		}
		return (*ptrDo)(ptrDo)
	})
	return func() int {
		return doFibo(&amp;doFibo)
	}
}

I apologize for my English.

huangapple
  • 本文由 发表于 2015年5月28日 17:45:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/30502933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定