在Go中通过类型引用的方法表达式会被还原成普通函数样式,接收者是第一个参数,调用时显示传参。

示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

type A int

func (a A) sum(b int) int {
	return int(a) + b
}

type B int

func (b B) sum() func(int) int {
	n := A(b)
	f := n.sum
	return f
}

func (b B) sum1(a int) int {
	return int(b) + a
}

func main() {
	f := B.sum
	n := f(2)(3)
	println("sum(2)(3)=", n)
	f1 := B.sum1
	n = f1(2, 3)
	println("sum(2, 3)=", n)
}

执行输出

1
2
sum(2)(3)= 5
sum(2, 3)= 5

看到这个结果,不经想起一道面试题:编写一个函数sum,使sum(2,3) 和 sum(2)(3)输出结果都是5

这道题如果用js或python很容易实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function sum() {
    var num = arguments[0];
    if(arguments.length==1){
        return function(sec){
            return num+sec;
        }
    }else{
        for(var i=1; i<arguments.length;i++){
            num += arguments[i];
        }
        return num;
    }
}

sum(2,3)
// 5
sum(2)(3)
// 5

在javascript 中 arguments 用在函数内部表示函数所有实参。

用python实现如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def sum(*args):
    if len(args) == 2:
            print args[0] + args[1]
    if len(args) == 1:
            return lambda a: a+args[0]

sum(2,3)
# 5
sum(2)(3)
# 5

那么在golang语言中能不能实现呢,答案是不能,Go 不支持真正的函数柯里化(Currying),

但链式调用可以像上面的示例一样,通过类型引用的方法表达式来实现。

参考