2015-01-20 8 views
6

मेरे पास एक आकार का बाइट सरणी है जिसे मुझे md5.Sum() करने के बाद मिला।क्यों [आकार] बाइट को स्ट्रिंग में कनवर्ट नहीं कर सकते?

data := []byte("testing") 
var pass string 
var b [16]byte 
b = md5.Sum(data) 
pass = string(b) 

त्रुटि:

pass = string(b[:]) 

लेकिन क्यों इस तरह इसका इस्तेमाल नहीं कर सकते हैं:

cannot convert b (type [16]byte) to type string 

मैं करने के लिए इस problem

बदलें पर समाधान खोजने?

pass = string(b) 

उत्तर

16

संक्षिप्त उत्तर इसलिए है क्योंकि गो भाषा विशिष्टता इसे अनुमति नहीं देती है।

Go Language Specification: Conversions से हवाला देते हुए:

A non-constant value x can be converted to type T in any of these cases:

  • x is assignable to T .
  • x 's type and T have identical underlying types.
  • x 's type and T are unnamed pointer types and their pointer base types have identical underlying types.
  • x's type and T are both integer or floating point types.
  • x's type and T are both complex types.
  • x is an integer or a slice of bytes or runes and T is a string type.
  • x is a string and T is a slice of bytes or runes.

विनिर्देश केवल string को बाइट या runes का एक टुकड़ा परिवर्तित करने की अनुमति देता है, लेकिन नहीं बाइट्स की एक सरणी।

लांग जवाब

जाओ सरणियों और स्लाइस में अलग प्रकार के होते हैं। सरणी का आकार प्रकार का हिस्सा है।

स्लाइस ज्यादा सरणियों की तुलना में अधिक सामान्य हैं, और एक टुकड़ा जो मूल्यों की इसी श्रृंखला का प्रतिनिधित्व करता है के लिए एक सरणी परिवर्तित बहुत आसान है: arr[:] (और भी सस्ता है, परिणाम टुकड़ा अपने समर्थन सरणी के रूप में सरणी साझा करेंगे, कोई पुनर्वितरण या प्रतिलिपि किया जाएगा)।

इस वजह से, सभी कार्यों और समर्थन स्लाइस के लिए प्रदान किए जाते हैं, न कि सरणी के लिए।

बस छवि आप एक साधारण फ़ंक्शन बनाना चाहते हैं जो int संख्याओं का एक टुकड़ा (किसी भी लंबाई के साथ) लेता है और संख्याओं का योग देता है। कुछ इस तरह:

func sum(s []int) (sum int) { 
    for _, v := range s { 
     sum += v 
    } 
    return 
} 

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

func sum2(s [2]int) (sum int) { 
    for _, v := range s { 
     sum += v 
    } 
    return 
} 

आप प्रकार [2]int के मूल्यों के साथ केवल sum2() कॉल कर सकते हैं, लेकिन यदि आप प्रकार [3]int की एक सरणी है, तो आप नहीं कर सकते उन 2 क्योंकि प्रकार अलग कर रहे हैं! यदि आप केवल int (आप स्लाइस की बैकिंग सरणी तक नहीं पहुंच सकते हैं) का टुकड़ा है तो आप sum2() पर भी कॉल नहीं कर सकते हैं। इस बीच आप अपने sum() फ़ंक्शन को सभी []int स्लाइस के साथ कॉल कर सकते हैं, और यदि आपके पास कोई सरणी है, तो भी आप arr[:] को sum() फ़ंक्शन पर पास करके इसका उपयोग कर सकते हैं।

नोट:

भी ध्यान रखें कि एक string बाइट्स के एक "यादृच्छिक" टुकड़ा परिवर्तित सबसे अधिक संभावना आप क्या चाहते हैं क्योंकि एक "यादृच्छिक" बाइट्स की टुकड़ा एक वैध UTF-8 बाइट नहीं हो सकता है नहीं है अनुक्रम।

इसके बजाय encoding/hex पैकेज का उपयोग इस तरह एक हेक्स स्ट्रिंग के लिए परिणाम कन्वर्ट करने के लिए:

fmt.Println(hex.EncodeToString(b[:])) 
+1

अपने बहुत विस्तृत उत्तर के लिए धन्यवाद, मैं समझता हूँ – soapbar

संबंधित मुद्दे