गो में वैकल्पिक पैरामीटर हो सकते हैं? या क्या मैं एक ही नाम और विभिन्न तर्कों के साथ दो कार्यों को परिभाषित कर सकता हूं?
गो में वैकल्पिक पैरामीटर हो सकते हैं? या क्या मैं एक ही नाम और विभिन्न तर्कों के साथ दो कार्यों को परिभाषित कर सकता हूं?
जवाबों:
गो में वैकल्पिक पैरामीटर नहीं है और न ही यह ओवरलोडिंग की विधि का समर्थन करता है :
विधि प्रेषण को सरल बनाया जाता है यदि उसे टाइप मिलान करने की आवश्यकता नहीं है। अन्य भाषाओं के साथ अनुभव ने हमें बताया कि एक ही नाम के साथ कई तरह के तरीके हैं लेकिन अलग-अलग हस्ताक्षर कभी-कभी उपयोगी होते हैं लेकिन यह व्यवहार में भ्रामक और नाजुक भी हो सकता है। केवल नाम से मिलान और प्रकारों में निरंतरता की आवश्यकता गो के प्रकार प्रणाली में एक प्रमुख सरलीकरण निर्णय था।
make
एक विशेष मामला तो? या क्या यह वास्तव में एक फ़ंक्शन के रूप में लागू नहीं किया गया है ...
make
एक भाषा निर्माण है और ऊपर उल्लिखित नियम लागू नहीं होते हैं। इससे संबंधित प्रश्न देखें ।
range
इस make
अर्थ में, वैसा ही मामला है
वैकल्पिक मापदंडों की तरह कुछ हासिल करने का एक अच्छा तरीका है वैरेडिक आर्ग्स का उपयोग करना। फ़ंक्शन वास्तव में आपके द्वारा निर्दिष्ट किसी भी प्रकार का एक टुकड़ा प्राप्त करता है।
func foo(params ...int) {
fmt.Println(len(params))
}
func main() {
foo()
foo(1)
foo(1,2,3)
}
params
आप एक संरचना का उपयोग कर सकते हैं जिसमें पैरामीटर शामिल हैं:
type Params struct {
a, b, c int
}
func doIt(p Params) int {
return p.a + p.b + p.c
}
// you can call it without specifying all parameters
doIt(Params{a: 1, c: 9})
मनमाने ढंग से, संभावित रूप से बड़ी संख्या में वैकल्पिक मापदंडों के लिए, एक अच्छा मुहावरा कार्यात्मक विकल्पों का उपयोग करना है ।
अपने प्रकार के लिए Foobar
, पहले केवल एक निर्माता लिखें:
func NewFoobar(options ...func(*Foobar) error) (*Foobar, error){
fb := &Foobar{}
// ... (write initializations with default values)...
for _, op := range options{
err := op(fb)
if err != nil {
return nil, err
}
}
return fb, nil
}
जहां प्रत्येक विकल्प एक फ़ंक्शन है जो फ़ॉबर को म्यूट करता है। फिर अपने उपयोगकर्ता को मानक विकल्प का उपयोग करने या बनाने के लिए सुविधाजनक तरीके प्रदान करें, उदाहरण के लिए:
func OptionReadonlyFlag(fb *Foobar) error {
fb.mutable = false
return nil
}
func OptionTemperature(t Celsius) func(*Foobar) error {
return func(fb *Foobar) error {
fb.temperature = t
return nil
}
}
संक्षिप्तता के लिए, आप विकल्पों के प्रकार को एक नाम दे सकते हैं ( खेल का मैदान ):
type OptionFoobar func(*Foobar) error
यदि आपको अनिवार्य मापदंडों की आवश्यकता है, तो उन्हें वेरिएबल से पहले निर्माता के पहले तर्क के रूप में जोड़ें options
।
कार्यात्मक विकल्प मुहावरे के मुख्य लाभ हैं:
यह तकनीक रॉब पाइक द्वारा गढ़ी गई थी और डेव चेनी द्वारा भी प्रदर्शित की गई थी ।
func()
अगर जरूरत पड़ सकते हैं, तो इस दृष्टिकोण से अपने मस्तिष्क को मोड़ सकते हैं। जब भी मुझे इस दृष्टिकोण का उपयोग करना होता है, जैसे कि इको लाइब्रेरी के साथ, मुझे लगता है कि मेरा मस्तिष्क गर्भपात के खरगोश के छेद में फंस गया है। # एफवी
गो में न तो वैकल्पिक पैरामीटर और न ही फ़ंक्शन ओवरलोडिंग का समर्थन किया जाता है। जाओ मापदंडों की एक चर संख्या का समर्थन करता है: तर्कों को पारित करना ... मापदंडों
न - न। C ++ प्रोग्रामर डॉक्स के लिए प्रति गो ,
जाओ फ़ंक्शन ओवरलोडिंग का समर्थन नहीं करता है और उपयोगकर्ता परिभाषित ऑपरेटरों का समर्थन नहीं करता है।
मैं समान रूप से स्पष्ट कथन नहीं ढूँढ सकता कि वैकल्पिक पैरामीटर असमर्थित हैं, लेकिन वे समर्थित नहीं हैं।
आप नीचे दिए गए एक फंक के समान इसे अच्छी तरह से अलग कर सकते हैं।
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
fmt.Println(prompt())
}
func prompt(params ...string) string {
prompt := ": "
if len(params) > 0 {
prompt = params[0]
}
reader := bufio.NewReader(os.Stdin)
fmt.Print(prompt)
text, _ := reader.ReadString('\n')
return text
}
इस उदाहरण में, डिफ़ॉल्ट रूप से संकेत में एक बृहदान्त्र और उसके सामने एक स्थान है। । ।
:
। । । हालाँकि, आप प्रॉम्प्ट फ़ंक्शन के पैरामीटर की आपूर्ति करके उसे ओवरराइड कर सकते हैं।
prompt("Input here -> ")
यह नीचे की तरह एक संकेत होगा।
Input here ->
मैंने पैरामस और वैरेडिक आर्ग्स की संरचना के संयोजन का उपयोग करके समाप्त किया। इस तरह, मुझे मौजूदा इंटरफ़ेस को बदलना नहीं पड़ा जो कि कई सेवाओं द्वारा खपत किया गया था और मेरी सेवा आवश्यकतानुसार अतिरिक्त पैरामेट्स पास करने में सक्षम थी। गोलंग खेल के मैदान में नमूना कोड: https://play.golang.org/p/G668FA97Nu
मुझे थोड़ी देर हो गई है, लेकिन यदि आप धाराप्रवाह इंटरफ़ेस पसंद करते हैं, तो आप इस तरह से जंजीर कॉल के लिए अपने बसने को डिज़ाइन कर सकते हैं:
type myType struct {
s string
a, b int
}
func New(s string, err *error) *myType {
if s == "" {
*err = errors.New(
"Mandatory argument `s` must not be empty!")
}
return &myType{s: s}
}
func (this *myType) setA (a int, err *error) *myType {
if *err == nil {
if a == 42 {
*err = errors.New("42 is not the answer!")
} else {
this.a = a
}
}
return this
}
func (this *myType) setB (b int, _ *error) *myType {
this.b = b
return this
}
और फिर इसे इस तरह से कॉल करें:
func main() {
var err error = nil
instance :=
New("hello", &err).
setA(1, &err).
setB(2, &err)
if err != nil {
fmt.Println("Failed: ", err)
} else {
fmt.Println(instance)
}
}
यह @Ripounet उत्तर पर प्रस्तुत कार्यात्मक विकल्प मुहावरे के समान है और समान लाभ प्राप्त करता है लेकिन इसमें कुछ कमियां हैं:
err
वैरिएबल घोषित करने और इसे शून्य करने के लिए एक लाइन खर्च करनी होगी ।हालांकि, एक संभावित छोटा लाभ है, इस प्रकार के फ़ंक्शन कॉल को इनलाइनर इनलाइन के लिए आसान होना चाहिए लेकिन मैं वास्तव में विशेषज्ञ नहीं हूं।
आप नक्शे के साथ मनमाने ढंग से नामित मापदंडों को पारित कर सकते हैं।
type varArgs map[string]interface{}
func myFunc(args varArgs) {
arg1 := "default" // optional default value
if val, ok := args["arg1"]; ok {
// value override or other action
arg1 = val.(string) // runtime panic if wrong type
}
arg2 := 123 // optional default value
if val, ok := args["arg2"]; ok {
// value override or other action
arg2 = val.(int) // runtime panic if wrong type
}
fmt.Println(arg1, arg2)
}
func Test_test() {
myFunc(varArgs{"arg1": "value", "arg2": 1234})
}
एक अन्य संभावना एक संरचना का उपयोग करने के लिए होगी जो यह इंगित करने के लिए फ़ील्ड के साथ है कि क्या यह वैध है। NullString जैसे sql से अशक्त प्रकार सुविधाजनक हैं। अपने स्वयं के प्रकार को परिभाषित न करने के लिए अच्छा है, लेकिन यदि आपको एक कस्टम डेटा प्रकार की आवश्यकता है तो आप हमेशा उसी पैटर्न का पालन कर सकते हैं। मुझे लगता है कि वैकल्पिक-परिभाषा फ़ंक्शन परिभाषा से स्पष्ट है और न्यूनतम अतिरिक्त कोड या प्रयास है।
उदहारण के लिए:
func Foo(bar string, baz sql.NullString){
if !baz.Valid {
baz.String = "defaultValue"
}
// the rest of the implementation
}