मेरे पास एक पुनरावर्ती कार्य है और मैं चाहता हूं कि कोई केवल फ़ंक्शन के सबसे बाहरी कॉल के लिए कुछ कथन निष्पादित करे। मैं इस कार्यक्षमता को कैसे प्राप्त करूं?
func fact(n int) int {
if n == 0 {
return 1
}
fact := n * fact(n-1)
if outer_most{
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4)
}
इसे केवल 4
प्रिंट करना चाहिए
4 जवाब
प्रश्न का उत्तर देने के लिए: यदि किसी कारण से आप वास्तव में कुछ ऐसा चलाना चाहते हैं जो केवल सबसे बाहरी func कॉल के लिए है और एपीआई को बदलना नहीं चाहते हैं, तो गोलंग के पास रनटाइम लिब है। आप इसे इस प्रकार कर सकते हैं:
package main
import (
"fmt"
"runtime"
"strconv"
)
func outer_most() bool {
pc:=make([]uintptr,2)
runtime.Callers(2,pc) //skip: 1 - runtime.Caller, 2 - outer_most itself
return runtime.FuncForPC(pc[0])!=runtime.FuncForPC(pc[1]) // test if the caller of the caller is the same func, otherwise it is the outermost
}
func fact(n int) int {
if n == 0 {
return 1
}
fact := n * fact(n-1)
if outer_most() {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4)
}
खेल का मैदान: https://play.golang.org/p/ro1ZOn6yIR7 यह कोई अच्छा अभ्यास नहीं है, लेकिन प्रश्न को सबसे सीधे तरीके से हल करें।
नोट: वैश्विक चर का उपयोग करने से गड़बड़ियां होने की बहुत संभावना है। जब भी आप func को कॉल करते हैं, तो आपको इसे हर बार सेट करने की आवश्यकता होती है, और यदि समरूपता है, तो डेटा दौड़ शामिल होगी।
और यदि आप इस तथ्य से असहज हैं कि अतिरिक्त बूल तर्क प्रत्येक रिकर्सिव कॉल आवंटित किया जाता है (जो अनगिनत बार हो सकता है), तो आप @Adrian के उत्तर को देख सकते हैं या इसे बूल की विधि के रूप में लपेट सकते हैं।
आप एक depth
जैसा कुछ पास कर सकते हैं जो प्रत्येक कॉल पर बढ़ता जाता है। जैसे:
func fact(depth int, n int) int {
if n == 0 {
return 1
}
fact := n * fact(depth + 1, n-1)
if depth == 0 {
fmt.Println(fact) // I assume you meant to print fact here.
}
return fact
}
func main() {
fact(0, 4)
}
यदि यह वास्तव में आपका उपयोग मामला है, तो आप ऐसा करने से काफी बेहतर हैं:
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fmt.Println(fact(4))
}
संपादित प्रश्न का उत्तर:
आप नीचे दिए गए दूसरे पैटर्न का फिर से उपयोग कर सकते हैं:
func fact(n int, outerMost bool) int {
if n == 0 {
return 1
}
fact := n * fact(n-1, false)
if outerMost {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4, true)
}
फिर से, आप इसे साफ करने के लिए क्लोजर या हेल्पर फ़ंक्शंस का उपयोग कर सकते हैं।
मूल उत्तर:
वैश्विक चर का उपयोग करने का प्रयास करें:
var outerMost bool = true
func fact(n int) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fact(4)
}
इसे हासिल करने के और भी तरीके हैं। उदाहरण के लिए, आप क्लोजर के साथ भी इसी तरह की तकनीक का उपयोग कर सकते हैं। या fact
में एक और पैरामीटर जोड़ें:
func fact(n int, outerMost bool) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1, outerMost)
}
func main() {
fact(4, true)
}
एक साधारण अनाम फ़ंक्शन शायद सबसे साफ है, क्योंकि यह एक पैरामीटर नहीं जोड़ता है, बाहरी कॉलर्स के लिए एपीआई को केवल आंतरिक तर्क को लागू करने के लिए जटिल करता है।
func fact(n int) int {
var facto func(n int) int
facto = func(n int) int {
if n == 0 {
return 1
}
fact := n * facto(n-1)
return fact
}
n = facto(n)
fmt.Printf("%d", n)
return n
}
यह समान कार्यक्षमता प्राप्त करता है, लेकिन कॉलर को अतिरिक्त बूल या int मान पास करने के बारे में जानने की आवश्यकता नहीं है जो इसके लिए अप्रासंगिक है। यहां पूरा उदाहरण: https://play.golang.org/p/7vHwPDN2_FL
संबंधित सवाल
नए सवाल
go
गो एक ओपन-सोर्स प्रोग्रामिंग भाषा है। यह स्वत: मेमोरी प्रबंधन, प्रकार सुरक्षा, कुछ गतिशील टाइपिंग क्षमताओं, अतिरिक्त अंतर्निहित प्रकार जैसे चर-लंबाई सरणियों (स्लाइस कहा जाता है) और कुंजी-मान मानचित्रों को जोड़ने के लिए, सी से व्युत्पन्न एक वाक्यविन्यास के साथ सांख्यिकीय रूप से टाइप किया जाता है, और बड़े मानक पुस्तकालय।