क्या कार्यों को मापदंडों के रूप में पारित किया जा सकता है?


158

जावा में मैं कुछ ऐसा कर सकता हूं

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

और बाद में विधि में "रन" कोड। इसे संभालने के लिए एक दर्द है (अनाम आंतरिक वर्ग), लेकिन यह किया जा सकता है।

क्या गो के पास कुछ ऐसा है जो एक फ़ंक्शन / कॉलबैक को एक पैरामीटर के रूप में पारित करने की सुविधा प्रदान कर सकता है?


7
पाठकों के लिए नाइट / स्पष्टीकरण: जावा में, "फ़ंक्शंस" पास करने योग्य नहीं हैं (वास्तव में, जावा में सभी "फ़ंक्शंस" अधिक उपयुक्त तरीके कहलाते हैं)। Runnable (और अनाम आंतरिक वर्ग जो उस से उत्पन्न होते हैं) बस इतना ही हैं: एक प्रकार जिसमें से वस्तुओं को तत्काल इंटरफ़ेस के लिए सब्सक्राइब किया जाता है ..

2
(छह साल बाद ...) जावा के पास अब तरीके (जैसे 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 के बजाय कुछ और प्रिंट कर सकें? वैश्विक चर घोषित किए बिना।
शनि

1
यदि मैं आपके प्रश्न को सही ढंग से समझता हूं, तो मुझे लगता है कि आप एक ऐसी फ़ंसी की तलाश कर रहे हैं, जो एक फ़नक लौटाता है, यहाँ देखें कि मैं एक "उद्धरण" फ़ंक्शन के साथ हार्डकोड "quot123" फ़ंक्शन को कैसे प्रतिस्थापित करता हूं जो आपको कुछ इनपुट पास करने के बाद उसी परिणाम को प्राप्त करता है: play.golang.org/p/52ahWAI2xsG
dskinner

34

आप फ़ंक्शन को गो फ़ंक्शन के पैरामीटर के रूप में पास कर सकते हैं। दूसरे फ़ंक्शन के पैरामीटर के रूप में फ़ंक्शन पास करने का एक उदाहरण यहां दिया गया है:

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
धन्यवाद! यह इस विचार का सबसे अच्छा उपयोग करने का एक बहुत स्पष्ट उदाहरण था! आपके द्वारा निष्पादित किए जाने वाले फ़ंक्शन के लिए एक पॉइंटर सहित, जानकारी संग्रहीत करने वाली संरचना के लुकअप टेबल का उपयोग करके मैंने इसे फिर से बनाया है। इसके लिए बिल्कुल सही!
जेम्स ओ'टोल

15

यहाँ गो में नमूना "मानचित्र" कार्यान्वयन है। उम्मीद है की यह मदद करेगा!!

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
यह एक समारोह में एक समारोह से गुजर नहीं लौट रहा है
जॉन लॉर्ज

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

हां गो प्रथम श्रेणी के कार्यों को स्वीकार करता है।

उपयोगी लिंक के लिए लेख "गो में प्रथम श्रेणी के कार्य" देखें


4
कृपया इस प्रतिक्रिया पर विस्तार करें; एक उदाहरण, संदर्भ से लिंक (उदाहरण के लिए वास्तविक संदर्भ), आदि शामिल हैं

3
वास्तव में उस पृष्ठ पर 0 जानकारी है, केवल स्रोत कोड द्वारा बेवकूफ उदाहरण के लिए लिंक।
OZ_
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.