Go语言是否具有类似于Lambda表达式的东西?

114

Go支持lambda表达式或类似的东西吗?

我想从使用lambda表达式(Ruby)的另一种语言移植一个库。


7
Go语言支持匿名函数(anonymous functions),但不支持像 x -> x+1 这样的短函数字面量(short function literals)。 - Ferran Maylinch
自2017年以来,关于在Go语言中缩短匿名函数语法的提案正在讨论中:https://github.com/golang/go/issues/21498 - jcsahnwaldt Reinstate Monica
7个回答

94
是的。 这里有一个例子,小心地复制和粘贴:链接
package main

import fmt "fmt"

type Stringy func() string

func foo() string{
  return "Stringy function"
}

func takesAFunction(foo Stringy){
  fmt.Printf("takesAFunction: %v\n", foo())
}

func returnsAFunction()Stringy{
  return func()string{
    fmt.Printf("Inner stringy function\n");
    return "bar" // have to return a string to be stringy
  }
}

func main(){
  takesAFunction(foo);
  var f Stringy = returnsAFunction();
  f();
  var baz Stringy = func()string{
    return "anonymous stringy\n"
  };
  fmt.Printf(baz());
}

33
我很愿意看到你提出的问题中不只是复制的代码。首先,你可以添加一个“是”、“否”、“部分”等答案。然后再加上一些描述,说明你的代码实际上是用来做什么的。 - Kissaki
4
Kissaki基本上是将函数传递给其他函数,并从函数中返回函数,代码本身已经很清晰易懂了,命名也很巧妙,takesaFunction接收一个函数然后返回字符串,returnsAFunction返回一个能返回字符串的函数......所以说......是的......完美地支持lambda表达式吧 :D - clagccs
2
这里真正需要的一个例子是一个带有参数并在声明时被调用的lambda函数的示例。 - Omnifarious
为什么在主函数中有一些分号?这是否会编译通过某个版本的Go编译器? - Szymon Brych
我只是想指出type不是必需的。你可以直接声明func takesAFunction(foo func()string) - Ferran Maylinch
显示剩余2条评论

57

13
这是最佳答案。我想补充一点,通常人们认为“lambda”是指像 x -> x+1 这样的短函数字面量,但是 Go 不支持这种语法,所以你必须编写完整的 func (x int) { return x+1 } - Ferran Maylinch

20

是的

在计算机编程中,匿名函数或lambda抽象(函数字面量)是一个不绑定到标识符的函数定义,并且Go支持匿名函数,它们可以形成闭包。当您想要内联定义一个函数而不必命名它时,匿名函数非常有用。

    package main
    import "fmt"

    func intSeq() func() int {
        i := 0
        return func() int {
            i += 1
            return i
        }
    }


    func main() {
       nextInt := intSeq()
       fmt.Println(nextInt())
       fmt.Println(nextInt())
       fmt.Println(nextInt())
       newInts := intSeq()
       fmt.Println(newInts())
    }

函数intSeq返回另一个函数,我们在intSeq的主体中匿名定义该函数。 返回的函数通过封闭变量i形成闭包

Output
$ go run closures.go
1
2
3
1

从 https://gobyexample.com/closures 逐字翻译: - Paolo

13

golang似乎没有lambda表达式,但您可以使用匿名函数,我在学习时编写了一些示例,比较了JS中的等效方法!

无参数返回字符串:

func() string {
    return "some String Value"
}
//Js similar: () => 'some String Value'

带字符串参数并返回字符串

func(arg string) string {
    return "some String" + arg
}
//Js similar: (arg) => "some String Value" + arg

无参数和无返回值(void)

func() {
   fmt.Println("Some String Value")
} 
//Js similar: () => {console.log("Some String Value")}

带参数无返回值(void)

func(arg string) {
    fmt.Println("Some String " + arg)
}
//Js: (arg) => {console.log("Some String Value" + arg)}

很棒的答案,只是缺少自动运行()的示例。 - Hasan A Yousef
2
Go支持匿名函数和高阶函数,因此它确实允许您“创建lambda表达式”。例如+1。 - user12817546

3
一个尚未提供的示例是直接从匿名函数向变量分配值,例如:
test1, test2 := func() (string, string) {
    x := []string{"hello", "world"}
    return x[0], x[1]
}()

注意:在函数末尾需要加上括号()来执行它并返回其值,否则只会返回函数本身并导致assignment mismatch: 2 variable but 1 values错误。

在JavaScript中,这种模式被称为立即调用函数表达式(参见MDN上的IIFE文档),用于在模块中隐藏变量或更改var变量的作用域。 - Carl Walsh

2
这是一个“柯里化函数”的例子。然而,相对于Swift、C#等其他语言中的lambda函数语法,该语法似乎不够清晰。
func main() int { 
  var f func(string) func(string) int
  f = func(_x1 string) func(string) int { return func(_x2 string) int { return strings.Compare(_x1,_x2) } }
  return ((f)("b"))("a")
}

0

是的,因为它是一种完全功能的语言,但没有像通常的lambda符号那样的fat arrow(=>)或thin arrow(->),而是为了清晰和简单起见使用func关键字。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接