함수를 매개 변수로 전달할 수 있습니까?


158

Java에서는 다음과 같은 작업을 수행 할 수 있습니다

derp(new Runnable { public void run () { /* run this sometime later */ } })

나중에 메소드에서 코드를 "실행"하십시오. 처리하기가 쉽지 않지만 (익명 내부 클래스) 할 수 있습니다.

Go에는 함수 / 콜백을 매개 변수로 전달할 수있는 기능이 있습니까?


7
독자를위한 힌트 / 설명 : Java에서는 "함수"를 전달할 수 없습니다 (실제로 Java의 모든 "함수"는 더 적절하게 메소드라고합니다). 실행 가능한 (그리고 그에서 파생 된 익명의 내부 클래스)입니다 단지 : 개체가 필요한 인터페이스에 가입 .. 인스턴스화되는 유형

2
(6 년 후 ...) Java는 이제 메소드를 전달하는 방법을 가지고있다 (예 containingObject::instanceMethodName: docs.oracle.com/javase/tutorial/java/javaOO/…
vazor

답변:


225

예, 다음 예 중 일부를 고려하십시오.

package main

import "fmt"

// convert types take an int and return a string value.
type convert func(int) string

// value implements convert, returning x as string.
func value(x int) string {
    return fmt.Sprintf("%v", x)
}

// quote123 passes 123 to convert func and returns quoted string.
func quote123(fn convert) string {
    return fmt.Sprintf("%q", fn(123))
}

func main() {
    var result string

    result = value(123)
    fmt.Println(result)
    // Output: 123

    result = quote123(value)
    fmt.Println(result)
    // Output: "123"

    result = quote123(func(x int) string { return fmt.Sprintf("%b", x) })
    fmt.Println(result)
    // Output: "1111011"

    foo := func(x int) string { return "foo" }
    result = quote123(foo)
    fmt.Println(result)
    // Output: "foo"

    _ = convert(foo) // confirm foo satisfies convert at runtime

    // fails due to argument type
    // _ = convert(func(x float64) string { return "" })
}

플레이 : http://play.golang.org/p/XNMtrDUDS0

둘러보기 : https://tour.golang.org/moretypes/25 (함수 폐쇄)


자체 매개 변수이기도 한 함수에 매개 변수를 전달할 수 있습니까? 위의 예에서, 인쇄되는 것은 하드 코딩되었습니다 : 인쇄 123. 123이 아닌 다른 것을 인쇄 할 수 있도록 변경이 가능합니까? 전역 변수를 선언하지 않고
Saty

1
귀하의 질문을 올바르게 이해하면 func을 반환하는 func을 찾고 있다고 생각합니다. 하드 코딩 된 "quote123"함수를 입력을 전달한 후 동일한 결과를 얻는 "quote"함수로 바꾸는 곳을 참조하십시오. play.golang.org/p/52ahWAI2xsG
dskinner

34

기능을 매개 변수로 Go 기능에 전달할 수 있습니다. 다음은 다른 Go 함수에 매개 변수로 함수를 전달하는 예입니다.

package main

import "fmt"

type fn func(int) 

func myfn1(i int) {
    fmt.Printf("\ni is %v", i)
}
func myfn2(i int) {
    fmt.Printf("\ni is %v", i)
}
func test(f fn, val int) {
    f(val)
}
func main() {
    test(myfn1, 123)
    test(myfn2, 321)
}

https://play.golang.org/p/9mAOUWGp0k 에서 시도해보십시오.


2
감사합니다! 이것은이 아이디어를 가장 잘 사용하는 방법에 대한 분명한 예입니다! 실행하려는 함수에 대한 포인터를 포함하여 정보를 저장하는 구조체의 조회 테이블을 사용하여 다시 작성했습니다. 이것에 딱!
James O'Toole

15

다음은 Go의 샘플 "Map"구현입니다. 도움이 되었기를 바랍니다!!

func square(num int) int {
    return num * num
}

func mapper(f func(int) int, alist []int) []int {
    var a = make([]int, len(alist), len(alist))
    for index, val := range alist {

        a[index] = f(val)
    }
    return a
}

func main() {
    alist := []int{4, 5, 6, 7}
    result := mapper(square, alist)
    fmt.Println(result)

}

8

다음은 간단한 예입니다.

    package main

    import "fmt"

    func plusTwo() (func(v int) (int)) {
        return func(v int) (int) {
            return v+2
        }
    }

    func plusX(x int) (func(v int) (int)) {
       return func(v int) (int) {
           return v+x
       }
    }

    func main() {
        p := plusTwo()
        fmt.Printf("3+2: %d\n", p(3))

        px := plusX(3)
        fmt.Printf("3+3: %d\n", px(3))
    }

4
그것은 함수를 전달하지 않는 함수를 반환합니다
John LaBarge

2

아래 예제가 더 명확 해지기를 바랍니다.

package main

type EmployeeManager struct{
    category            string
    city                string
    calculateSalary     func() int64
}


func NewEmployeeManager() (*EmployeeManager,error){

    return &EmployeeManager{
        category : "MANAGEMENT",
        city : "NY",
        calculateSalary: func() int64 {
            var calculatedSalary int64
            // some formula
            return calculatedSalary
        },
    },nil
}

func (self *EmployeeManager) emWithSalaryCalculation(){
    self.calculateSalary = func() int64 {
        var calculatedSalary int64
        // some new formula
        return calculatedSalary
    }
}

func updateEmployeeInfo(em EmployeeManager){
    // Some code
}

func processEmployee(){
    updateEmployeeInfo(struct {
        category        string
        city            string
        calculateSalary func() int64
    }{category: "", city: "", calculateSalary: func() int64 {
        var calculatedSalary int64
        // some new formula
        return calculatedSalary
    }})
}

-2

예 Go는 일류 기능을 수용합니다.

유용한 링크에 대해서는 "Go Class 클래스 기능" 기사를 참조하십시오 .


4
이 응답을 확장하십시오. 예를 들어, 참조 링크 (예 : 실제 참조) 등을 포함

3
실제로 해당 페이지에는 0 개의 정보가 있으며 소스 코드로 바보 같은 예제에만 연결됩니다.
OZ_
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.