जब मैं कहता हूं { :bla => 1, :bloop => 2 }
, वास्तव में क्या करता :
है? मैंने कहीं पढ़ा कि यह कैसे एक स्ट्रिंग के समान है, लेकिन किसी तरह एक प्रतीक।
मैं इस अवधारणा पर सुपर स्पष्ट नहीं हूं, क्या कोई मुझे बता सकता है?
जब मैं कहता हूं { :bla => 1, :bloop => 2 }
, वास्तव में क्या करता :
है? मैंने कहीं पढ़ा कि यह कैसे एक स्ट्रिंग के समान है, लेकिन किसी तरह एक प्रतीक।
मैं इस अवधारणा पर सुपर स्पष्ट नहीं हूं, क्या कोई मुझे बता सकता है?
जवाबों:
:foo
"फू" नाम का एक प्रतीक है। प्रतीकों की विशिष्ट विशेषता यह है कि किसी भी नाम के दो प्रतीक समान होंगे:
"foo".equal? "foo" # false
:foo.equal? :foo # true
यह दो प्रतीकों की तुलना वास्तव में तेजी से करता है (चूंकि केवल एक सूचक तुलना शामिल है, जैसा कि आप एक स्ट्रिंग में सभी वर्णों की तुलना करने के लिए विरोध करते हैं), साथ ही आपके पास एक ही प्रतीक की एक zillion प्रतियां नहीं होंगी।
इसके अलावा, तार के विपरीत, प्रतीक अपरिवर्तनीय हैं।
"foo".equal? "foo"
झूठा क्यों है ? ख) क्या आप कहीं भी एक प्रतीक का उल्लेख कर सकते हैं, अनिवार्य रूप से उन्हें वैश्विक चर की तरह बना सकते हैं?
equal?
रूबी में पहचान तुलना करता है। प्रत्येक स्ट्रिंग शाब्दिक, जैसे "foo"
, एक नया स्ट्रिंग उदाहरण बनाता है। यह उस तरह से काम करता है क्योंकि रूबी में तार परस्पर भिन्न होते हैं। 2. प्रतीक वैश्विक हैं, लेकिन वैश्विक चर की तुलना में वैश्विक स्थिरांक अधिक हैं, क्योंकि प्रतीकों में राज्य नहीं है। इस प्रकार प्रतीकों का उपयोग करना उस तरह से एक एंटीपैटर्न नहीं है जिस तरह से वैश्विक चर हैं।
"foo" == "foo"
# => सच
बस उत्तर में उल्लिखित कुछ चीजों को प्रदर्शित करने के लिए:
require 'benchmark'
n = 1_000_000
print '"foo".equal? "foo" -> ', ("foo".equal? "foo"), "\n"
print '"foo" == "foo" -> ', ("foo" == "foo" ), "\n"
print ':foo.equal? :foo -> ', (:foo.equal? :foo ), "\n"
print ':foo == :foo -> ', (:foo == :foo ), "\n"
Benchmark.bm(10) do |b|
b.report('string') { n.times { "foo".equal? "foo" }}
b.report('str == str') { n.times { "foo" == "foo" }}
b.report('symbol') { n.times { :foo.equal? :foo }}
b.report('sym == sym') { n.times { :foo == :foo }}
end
इसे आउटपुट देना:
"foo".equal? "foo" -> false
"foo" == "foo" -> true
:foo.equal? :foo -> true
:foo == :foo -> true
इसलिए, स्ट्रिंग का उपयोग करके स्ट्रिंग की तुलना करना equal?
विफल रहता है क्योंकि वे अलग-अलग ऑब्जेक्ट हैं, भले ही वे समान सामग्री हों। ==
सामग्री की तुलना करता है, और प्रतीकों के साथ समान जांच बहुत तेज होती है।
user system total real
string 0.370000 0.000000 0.370000 ( 0.371700)
str == str 0.330000 0.000000 0.330000 ( 0.326368)
symbol 0.170000 0.000000 0.170000 ( 0.174641)
sym == sym 0.180000 0.000000 0.180000 ( 0.179374)
दोनों प्रतीक परीक्षण मूल रूप से गति के समान ही हैं। 1,000,000 पुनरावृत्तियों के बाद केवल 0.004733 दूसरा अंतर है, इसलिए मैं कहूंगा कि यह एक वॉश है जिसके बीच उपयोग करना है।
==
तेजी से परिणाम हुआ .equal?
। स्ट्रिंग तुलना की तुलना में प्रतीक तुलना में 3+ गुना तेजी से हुआ।
प्रतीक माणिक में तार और नामों का प्रतिनिधित्व करने का एक तरीका है।
प्रतीकों और तारों के बीच मुख्य अंतर यह है कि एक ही नाम के प्रतीकों को आरंभीकृत किया जाता है और रूबी के सत्र के दौरान केवल एक बार स्मृति में मौजूद होता है।
वे उपयोगी होते हैं जब आपको विभिन्न चीजों का प्रतिनिधित्व करने के लिए एक ही शब्द का उपयोग करने की आवश्यकता होती है
रेल के साथ प्रसिद्ध पुस्तक एजाइल वेब डेवलपमेंट के कुछ उद्धरण हैं , जो प्रतीक को समझने में मददगार हो सकते हैं :
रेल चीजों को पहचानने के लिए प्रतीकों का उपयोग करता है। विशेष रूप से, यह विधि मापदंडों का नामकरण और हैश में चीजों को देखने पर कुंजी के रूप में उनका उपयोग करता है।
redirect_to :action => "edit", :id => params[:id]
आप प्रतीकों को स्ट्रिंग शाब्दिक के रूप में सोच सकते हैं जो जादुई रूप से स्थिरांक में बने होते हैं। वैकल्पिक रूप से, आप कोलन का अर्थ "नाम वाली चीज़" मान सकते हैं, इसलिए: आईडी "आईडी नाम की चीज़" है।
माणिक्य में प्रत्येक वस्तु की एक विशिष्ट वस्तु पहचानकर्ता होती है, यदि आप puts "hello".object_id
अपने irb में लिखते हैं और 2 अलग-अलग समयों के लिए वापसी करते हैं, तो आपको 2 अलग-अलग रिटर्निंग वैल्यू मिलेंगे, लेकिन यदि आप :hello.object_id
2 बार लिखते हैं तो आपको केवल एक ही रिटर्निंग वैल्यू मिलेगी। यह अंतर स्पष्ट करना चाहिए था।
यदि आप उपयोग करते हैं :foo => bar
, तो फू एक प्रतीक होगा। प्रतीकों का लाभ यह है कि वे अद्वितीय हैं। जब आप हैश में किसी आइटम पर कॉल करते हैं, तो आप करते हैं hash[:foo]
।
प्रतीकों को स्ट्रिंग्स की तुलना में कम स्मृति की आवश्यकता होती है, जो उन्हें उपयोगी बनाता है यदि आप अपने कार्यक्रम को थोड़ा तेज करना चाहते हैं।
ये सभी उत्तर एक अतिरिक्त तांत्रिक विस्तार को छोड़ते हैं .. यदि आप प्रतीक को कड़े करते हैं: फू, आपको मिलता है .. अनुमान लगाते हैं कि क्या है .. स्ट्रिंग "फू"। अत
irb(main):025:0>
irb(main):026:0> :foo
=> :foo
irb(main):027:0> "#{:foo}"
=> "foo"
irb(main):028:0>
irb(main):029:0> 'foo' <=> :foo
=> nil
irb(main):030:0> 'foo' <=> :foo.to_s
=> 0
irb(main):031:0>
इसलिए .. पर्ल प्रोग्रामर्स के लिए .. यह 'नंगे शब्द' रूबी का जवाब है।
यदि आप जावा से परिचित हैं, तो आप जानते होंगे कि जावा में स्ट्रिंग्स अपरिवर्तनीय हैं। रूबी में प्रतीक इस अर्थ में समान हैं। वे अपरिवर्तनीय हैं, अर्थात, किसी विशेष प्रतीक के किसी भी संख्या में :symbol
केवल एक ही मेमोरी पते पर मैप किया जाएगा। और, इसलिए, जहां भी संभव हो, प्रतीकों का उपयोग करने की सिफारिश की जाती है क्योंकि यह स्मृति उपयोग को अनुकूलित करता है।
NSString
। वहाँ "foo"
हमेशा बराबर करने के लिए किया जाएगा "foo"
, क्योंकि आंतरिक रूप से तार है कि एक ही बस की ओर इशारा कर रहे हैं। जवाब अभी भी भ्रामक होगा।