पूर्णांक द्वारा अवधि को कैसे गुणा करें?


284

समवर्ती गोरोइटिन का परीक्षण करने के लिए, मैंने इसे वापस करने के लिए एक यादृच्छिक समय लेने के लिए एक फ़ंक्शन में एक पंक्ति जोड़ी (एक सेकंड तक)

time.Sleep(rand.Int31n(1000) * time.Millisecond)

हालाँकि जब मैंने संकलित किया, तो मुझे यह त्रुटि मिली

। \ crawler.go: 49: अमान्य ऑपरेशन: rand.Int31n (1000) * time.Millisecond (बेमेल प्रकार int32 और time.Duration)

कोई विचार? मैं अवधि कैसे बढ़ा सकता हूं?

जवाबों:


431

int32और time.Durationविभिन्न प्रकार हैं। आपको int32time.Duration, जैसे कि में बदलने की जरूरत है time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)


5
धन्यवाद कि काम किया। मैंने यादृच्छिक संख्या जनरेटरrand.Seed(time.Now().Unix())
कर्नल पैनिक

44
सिर्फ मेरे ज्ञान के लिए, निम्नलिखित काम कैसे करता है? time.Sleep(time.Second * 2)
इशान खरे

59
यह काम करता है क्योंकि स्थिरांक का एक अनुकूल प्रकार होता है, जिसका उपयोग उनके उपयोग के आधार पर किया जाता है। रोब पाइक द्वारा इस ब्लॉग पोस्ट को देखें जो इसे विस्तार से बताता है: blog.golang.org/constants
mna

28
यह अपने साधारण प्रकार प्रणाली की वजह से ही बार में उन अजीब चीजों में से एक है (इस मामले में अधिक भार ऑपरेटर की कमी है) - आप के लिए गुणा कास्ट करने के लिए है Duration* Duration= Duration, बजाय मूल एक है जो वास्तव में अधिक समझ में आता है की: Duration* int= Duration
टिम्मम

14
अच्छी तरह से या तो ऑपरेटर ओवरलोडिंग या अंतर्निहित संख्यात्मक रूपांतरण इस काम को करने देगा। मुझे लगता है कि वे निहित सांख्यिक रूपांतरण को छोड़ने के लिए सही थे। इस पर पीछे देखने के बाद कि int64(...) * Durationढलाई से बहुत अधिक समझ में आता है Duration, जो इकाइयों का काम कैसे करना चाहिए, इसका सिर्फ एक मूल उल्लंघन है। अफसोस की बात है कि काम नहीं करता है। आपको वास्तव में ऐसा करना है Duration * Durationजो भयानक है।
टिम्मम

59

आपको इसे एक सही प्रारूप में डालना होगा Playground

yourTime := rand.Int31n(1000)
time.Sleep(time.Duration(yourTime) * time.Millisecond)

यदि आप नींद के लिए प्रलेखन की जांच करेंगे , तो आप देखते हैं कि इसे func Sleep(d Duration)एक पैरामीटर के रूप में अवधि की आवश्यकता है । आपकी रैंड.इंटर31 एन रिटर्न int32

उदाहरण से लाइन काम करती है ( time.Sleep(100 * time.Millisecond)) क्योंकि कंपाइलर यह समझने के लिए पर्याप्त स्मार्ट है कि यहां आपके निरंतर 100 का मतलब एक अवधि है। लेकिन यदि आप एक चर पास करते हैं, तो आपको इसे डालना चाहिए।


16

गो में, आप एक ही प्रकार के चर को गुणा कर सकते हैं, इसलिए आपको अभिव्यक्ति के दोनों हिस्सों को एक ही प्रकार का होना चाहिए।

सबसे आसान चीज जो आप कर सकते हैं वह एक पूर्णांक को अवधि से पहले गुणा करने के लिए कास्टिंग कर रहा है, लेकिन यह इकाई शब्दार्थ का उल्लंघन करेगा। इकाइयों के कार्यकाल में अवधि का गुणा क्या होगा?

मैं इसके बजाय time.illisecond को int64 में परिवर्तित करूँगा, और फिर इसे मिलीसेकंड की संख्या से गुणा करूँगा, फिर समय के लिए डालूँगा।

time.Duration(int64(time.Millisecond) * int64(rand.Int31n(1000)))

इस तरह अभिव्यक्ति के किसी भी भाग को उसके प्रकार के अनुसार सार्थक मूल्य कहा जा सकता है। int64(time.Millisecond)हिस्सा सिर्फ एक आयाम रहित मूल्य है - मूल मूल्य में समय की सबसे छोटी इकाइयों की संख्या।

यदि थोड़ा सरल मार्ग पर चलें:

time.Duration(rand.Int31n(1000)) * time.Millisecond

गुणन का बायां हिस्सा बकवास है - प्रकार का मान "समय। अवधि", इसके प्रकार के लिए कुछ अप्रासंगिक पकड़:

numberOfMilliseconds := 100
// just can't come up with a name for following:
someLHS := time.Duration(numberOfMilliseconds)
fmt.Println(someLHS)
fmt.Println(someLHS*time.Millisecond)

और यह सिर्फ शब्दार्थ नहीं है, वास्तविक कार्यक्षमता प्रकारों से जुड़ी है। यह कोड प्रिंट करता है:

100ns
100ms

दिलचस्प बात यह है कि, यहां कोड सैंपल सबसे सरल कोड का उपयोग करता है, अवधि रूपांतरण के समान भ्रामक शब्दार्थ के साथ: https://golang.org/pkg/time/#Duration

सेकंड: = 10

fmt.Print (time.Duration (सेकंड) * time.Second) // 10s प्रिंट करता है


5

यह अच्छा है कि गो के पास एक Durationप्रकार है - स्पष्ट रूप से परिभाषित इकाइयां होने से वास्तविक दुनिया की समस्याओं को रोका जा सकता है।

और गो के सख्त प्रकार के नियमों के कारण, आप एक पूर्णांक द्वारा अवधि को गुणा नहीं कर सकते हैं - आपको सामान्य प्रकार को गुणा करने के लिए एक कास्ट का उपयोग करना होगा

/*
MultiplyDuration Hide semantically invalid duration math behind a function
*/
func MultiplyDuration(factor int64, d time.Duration) time.Duration {
    return time.Duration(factor) * d        // method 1 -- multiply in 'Duration'
 // return time.Duration(factor * int64(d)) // method 2 -- multiply in 'int64'
}

आधिकारिक दस्तावेज विधि # 1 का उपयोग को दर्शाता है:

किसी पूर्णांक संख्या को एक अवधि में बदलने के लिए, गुणा करें:

seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s

लेकिन, निश्चित रूप से, एक अवधि को अवधि से गुणा करना एक अवधि का उत्पादन नहीं करना चाहिए - यह इसके चेहरे पर बकवास है। बिंदु में मामला, 5 मिलीसेकंड बार 5 मिलीसेकंड का उत्पादन करता है 6h56m40s। 5 सेकंड के वर्ग में प्रयास करने का परिणाम एक अतिप्रवाह होता है (और यह भी संकलित नहीं किया जाएगा यदि स्थिरांक के साथ किया जाता है)।

वैसे, नैनोसेकंड का int64प्रतिनिधित्व "सबसे अधिक प्रतिनिधित्व करने योग्य अवधि को लगभग 290 वर्षों तक सीमित करता है" , और यह इंगित करता है कि , जैसे , एक हस्ताक्षरित मूल्य के रूप में व्यवहार किया जाता है: और यह वास्तव में इसे कैसे लागू किया जाता है:DurationDurationint64(1<<(64-1))/(1e9*60*60*24*365.25) ~= 292

// A Duration represents the elapsed time between two instants
// as an int64 nanosecond count. The representation limits the
// largest representable duration to approximately 290 years.
type Duration int64

इसलिए, क्योंकि हम जानते हैं कि अंतर्निहित प्रतिनिधित्व Durationएक है int64, कलाकारों के बीच प्रदर्शन करना int64और Durationएक समझदार NO- ओपी है - केवल मिश्रण प्रकारों के बारे में भाषा नियमों को संतुष्ट करने के लिए आवश्यक है, और इसके बाद के गुणन ऑपरेशन पर इसका कोई प्रभाव नहीं है।

यदि आपको शुद्धता के कारणों के लिए कास्टिंग पसंद नहीं है, तो इसे फ़ंक्शन कॉल में दफन कर दें जैसा कि मैंने ऊपर दिखाया है।


" सामान्य रूप से / के साथ गुणा करें "।
नोबार

(गलत) उत्तर में विभाजन से संबंधित इसी तरह की चर्चा यहां दी गई है
nobar

-3

निम्नलिखित कोड का उपयोग करते हुए चर के गुणा करने के लिए

    oneHr:=3600
    addOneHrDuration :=time.Duration(oneHr)
    addOneHrCurrTime := time.Now().Add(addOneHrDuration*time.Second)

यह गो के time.Durationचर का उपयोग करने का एक अच्छा तरीका नहीं है । आप अपने addOneHrDurationसमय के चर का नाम देते हैं, time.Durationलेकिन फिर इसे एक घंटे तक नहीं बल्कि 3600 ns पर सेट करने के लिए आगे बढ़ते हैं। A time.Durationमें नैनोसेकंड की आधार इकाइयाँ होती हैं। वास्तव में एक घंटे की अवधि प्राप्त करने के लिए आप कुछ ऐसा कर सकते हैं: const oneHourDuration = 60 * time.Hour(या 3600 * time.Secondया time.Hour)।
डेव सी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.