स्ट्रिंग बाइट्स सरणी में कैसे असाइन करें


375

मैं स्ट्रिंग बाइट्स को असाइन करना चाहता हूं सरणी:

var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
  arr[k] = byte(v)
}

एक और तरीका है?


11
यदि की लंबाई लंबाई से strअधिक है arrतो आपको "इंडेक्स आउट ऑफ रेंज" त्रुटि मिलेगी।
पेट्रो

जवाबों:


542

सुरक्षित और सरल:

[]byte("Here is a string....")

14
जाओ में सर्वश्रेष्ठ कोडिंग प्रथाओं बाइट्स का एक टुकड़ा उपयोग कर रहा है []byteऔर नहीं बाइट्स का एक सेट सरणी [20]byteजब बाइट्स के लिए एक स्ट्रिंग परिवर्तित ... Do मुझे विश्वास नहीं है? इस धागे
ओपनवॉन्क

9
ओपी ने एक सरणी के बारे में पूछा, एक टुकड़ा नहीं। कुछ मामलों में आपको स्लाइस के आकार को सीमित करने और इसके बजाय एक सरणी का उपयोग करने की आवश्यकता होती है। नीचे दिए गए मेरे जवाब से यह सुनिश्चित होता है कि आप सरणी को ओवरफ्लो न करें।
डेविड एफजी

3
जो लोग सोचते हैं कि यह थोड़ा अजीब लगता है: यह गो में केवल प्रकार का रूपांतरण है: golang.org/ref/spec#Conversions
Cnly

किसी भी तरह कई तार जोड़ने और उन्हें समाप्‍त करने का कोई तरीका है? जैसे []byte("one", "two")?
राकिम

दुर्भाग्य से नहीं, @rakim, आप केवल एक स्ट्रिंग पास कर सकते हैं ... इसलिए, आपको उन्हें पहले संक्षिप्त करना होगा या बाइट्स के कई स्लाइस (इस प्रश्न के दायरे के बाहर) को संयोजित करना होगा।
खुला

149

स्ट्रिंग से बाइट स्लाइस में परिवर्तित करने के लिए string -> []byte:

[]byte(str)

किसी सरणी को एक स्लाइस में बदलने के लिए [20]byte -> []byte:

arr[:]

किसी स्ट्रिंग को एक सरणी में कॉपी करने के लिए string -> [20]byte:

copy(arr[:], str)

ऊपर के समान, लेकिन पहले स्पष्ट रूप से एक स्लाइस को स्ट्रिंग में परिवर्तित करना:

copy(arr[:], []byte(str))

  • में निर्मित copyसमारोह केवल प्रतियां करने के लिए एक टुकड़ा, से एक टुकड़ा।
  • ऐरे "अंतर्निहित डेटा" हैं, जबकि स्लाइस "अंतर्निहित डेटा में एक व्यूपोर्ट" हैं।
  • [:]एक सरणी का उपयोग स्लाइस के रूप में अर्हता प्राप्त करता है।
  • एक स्ट्रिंग एक स्लाइस के रूप में योग्य नहीं है जिसे कॉपी किया जा सकता है , लेकिन यह एक स्लाइस के रूप में अर्हता प्राप्त करता है जिसे (स्ट्रिंग्स अपरिवर्तनीय हैं) से कॉपी किया जा सकता है ।
  • यदि स्ट्रिंग बहुत लंबी है, copyतो केवल फिट होने वाले स्ट्रिंग के हिस्से को कॉपी करेगा।

यह कोड:

var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)

... निम्नलिखित उत्पादन देता है:

array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)

मैंने इसे गो प्लेग्राउंड में भी उपलब्ध कराया


आप एकल चरित्र को परिवर्तित करने के लिए एक उदाहरण जोड़ना चाह सकते हैं। मैं इससे b[i] = []byte("A")[0]काम करता हूं , लेकिन यह b[i] = 'A'बहुत साफ है।
एलेक्स जानसेन

1
यह मल्टी-बाइट रन के लिए काम नहीं करता है:b[1] = '本'
अलेक्जेंडर

110

उदाहरण के लिए,

package main

import "fmt"

func main() {
    s := "abc"
    var a [20]byte
    copy(a[:], s)
    fmt.Println("s:", []byte(s), "a:", a)
}

आउटपुट:

s: [97 98 99] a: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

3
यह एकमात्र उत्तर है जो वास्तव में मूल प्रश्न को संबोधित करता है।
जैक ओ'कॉनर

स्ट्रिंग के लिए वास्तव में आपके लिए विशिष्ट के बजाय 20 बाइट्स क्यों असाइन करें? यदि स्ट्रिंग की आवश्यकता 20 से कम है तो क्या यह अक्षम नहीं है? और अगर यह 20 से अधिक हो जाए, तो त्रुटि भी होती है?
सर

1
@ सायर: हम 20 बाइट्स नहीं देते हैं। हम 3 बाइट्स कॉपी करते हैं, की लंबाई s, `कॉपी फ़ंक्शन गूंगा नहीं है। स्लाइस को कॉपी और कॉपी करना : "कॉपी किए गए तत्वों की संख्या लेन (src) और लेन (dst) की न्यूनतम है।"
पेट्रोएस

42

केक का टुकड़ा:

arr := []byte("That's all folks!!")

8
यह प्रश्न का उत्तर नहीं लगता है। ओपी स्ट्रिंग के बाइट्स को मौजूदा सरणी में लिखना चाहता था जो स्ट्रिंग से अधिक लंबा हो सकता है।
जैक ओ'कॉनर

2
स्लाइस []byteका उपयोग सरणियों पर पसंद किया जाता है [20]byte। सर्वोत्तम प्रथाओं के आधार पर उत्तर सही है; यदि विनिर्देशों या कोड सरणियों की आवश्यकता होती है, तो copyइसके बजाय का उपयोग करें (इस थ्रेड में अन्यत्र उदाहरण देखें)।
ओपनवॉंक

25

मेरे विचार में बेहतर होगा कि..

package main

import "fmt"

func main() {
    str := "abc"
    mySlice := []byte(str)
    fmt.Printf("%v -> '%s'",mySlice,mySlice )
}

यहां देखें: http://play.golang.org/p/vpnAWHZZk7


3
यह बेहतर नहीं है। यह गलत है। यह वह नहीं करता है जो प्रश्न के लिए पूछा गया था।
पेट्रो

10

जाओ, एक स्ट्रिंग को बाइट्स स्लाइस में बदलें

[] स्ट्रिंग को [] बाइट प्रकार में बदलने के लिए आपको एक तेज़ तरीका चाहिए। टेक्स्ट डेटा को रैंडम एक्सेस फ़ाइल या अन्य प्रकार के डेटा हेरफेर में संग्रहीत करने जैसी स्थितियों में उपयोग करने के लिए इनपुट डेटा को [] बाइट प्रकार में रखने की आवश्यकता होती है।

package main

func main() {

    var s string

    //...

    b := []byte(s)

    //...
}

जो ioutil.WriteFile का उपयोग करते समय उपयोगी है, जो बाइट्स स्लाइस को अपने डेटा पैरामीटर के रूप में स्वीकार करता है:

WriteFile func(filename string, data []byte, perm os.FileMode) error

एक और उदाहरण

package main

import (
    "fmt"
    "strings"
)

func main() {

    stringSlice := []string{"hello", "world"}

    stringByte := strings.Join(stringSlice, " ")

    // Byte array value
    fmt.Println([]byte(stringByte))

    // Corresponding string value
    fmt.Println(string([]byte(stringByte)))
}

आउटपुट:

[१०४ १०] १० hel १० 104 १२१ ११ ९ १११ ११४ १० 100 १०० १०] हैलो दुनिया

कृपया लिंक खेल के मैदान की जाँच करें


0

इसे करने के लिए ऐरे विशिष्ट तरीकों का निर्माण किया। बहुत पसंद एन्कोडिंग / बाइनरी प्रत्येक पूर्णांक प्रकार के लिए विशिष्ट तरीकों के साथ पैकेज। उदाहरण के लिए binary.BigEndian.PutUint16([]byte, uint16)

func byte16PutString(s string) [16]byte {
    var a [16]byte
    if len(s) > 16 {
        copy(a[:], s)
    } else {
        copy(a[16-len(s):], s)
    }
    return a
}

var b [16]byte
b = byte16PutString("abc")
fmt.Printf("%v\n", b)

आउटपुट:

[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]

ध्यान दें कि मैं बाईं ओर कैसे पैडिंग चाहता था, न कि दाएं।

http://play.golang.org/p/7tNumnJaiN


3
यदि आप जवाब देने से वंचित हैं तो कृपया टिप्पणी छोड़ दें कि आप समाधान को इष्टतम क्यों नहीं पाते हैं या यह ओपी के प्रश्न के लिए कैसे प्रासंगिक नहीं है।
डेविडजी

3
मुझे लगता है कि डाउनवोट इसलिए हैं क्योंकि byte16PutStringयह बिल्टइन copyफ़ंक्शन के पुन: क्रियान्वयन का एक प्रकार है , जो केवल एक मौजूदा का उपयोग करने के बजाय नए सरणियों का निर्माण करने का समर्थन करता है। copyइसमें विशेष संकलक समर्थन है, इसलिए यह विभिन्न प्रकार के तर्कों को संभाल सकता है, और संभवतः इसमें कवर्स के तहत वास्तव में उच्च-प्रदर्शन कार्यान्वयन है। इसके अलावा, ओपी के सवाल ने एक नए को आवंटित करने के बजाय एक मौजूदा सरणी को एक स्ट्रिंग लिखने के बारे में पूछा, हालांकि अन्य जवाबों में से अधिकांश इसे भी अनदेखा करते प्रतीत होते हैं ...
जैक ओ'कॉनर

धन्यवाद @ JackO'Connor मैं यहां सीखने के लिए भी हूं और रचनात्मक प्रतिक्रिया की सराहना करता हूं, न कि केवल सादे नीचे।
डेविड

पता नहीं y इसकी नीचे मतदान answerसही है हर शरीर दूसरों को सीखने और प्रोत्साहित करने के लिए यहाँ है
मुथुकुमार हेलियस

-1

ऊपर बताए गए तरीकों के अलावा, आप एक ट्रिक भी कर सकते हैं

s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))

गो प्ले: http://play.golang.org/p/xASsiSpQmC

आप इस का उपयोग कभी नहीं करना चाहिए :-)


1
यह पागलपन है। मुझे लगता है कि यह जोड़ने लायक है "लेकिन आपको अपनी प्रतिक्रिया के अंत में नहीं" चाहिए। इस तथ्य के अलावा यह वास्तव में सवाल का जवाब नहीं देता है (ओपी बाइट्स सरणी के बारे में बात करता है, स्लाइस नहीं), आपको []byteअपने "रूपांतरण" का उपयोग करके एक उचित ऑब्जेक्ट नहीं मिलता है - जब आप संशोधन करने की कोशिश करते हैं तो यह बुरी तरह से विफल होता है p, देखें: play.golang.org/p/WHGl756ucj । आपके मामले में, यह निश्चित नहीं है कि आप इस b := []byte(s)पद्धति पर दोहरा-असुरक्षित क्यों पसंद करेंगे ।
tomasz

1
@tomasz मैं स्ट्रिंग करना पसंद नहीं कर रहा हूं <-> [] इस तरह से बाइट, बस एक अलग विकल्प दिखा रहा है :-) और हाँ आप सही हैं, मैंने सवाल गलत समझा।
ब्रैंडन गाओ

जब मैं ऐसा करता हूं, तो परिणाम में एक cap()मनमाना आकार होता है, जिसका अर्थ है कि यह अज्ञात मेमोरी में पढ़ रहा है। इसके लिए सही होने के लिए, मुझे लगता है कि आपको यह सुनिश्चित करने की आवश्यकता होगी कि आप पूर्ण reflect.SliceHeaderआकार आवंटित करें और मैन्युअल रूप से सेट करें cap। कुछ इस तरह: play.golang.org/p/fBK4dZM-qD
Lye Fish

और मैं इसके बारे में निश्चित नहीं हूं ।------------- ^ - शायद यह बेहतर है: play.golang.org/p/NJUxb20FTG
Lye Fish

-1

Arrays मान हैं ... स्लाइस पॉइंटर्स की तरह अधिक हैं। यह [n]typeसंगत नहीं है []typeक्योंकि वे मूलभूत रूप से दो अलग चीजें हैं। आप एक स्लाइस प्राप्त कर सकते हैं जो एक सरणी को इंगित करता है arr[:]जिसके द्वारा एक स्लाइस देता है जिसमें arrबैकिंग स्टोरेज है।

एक तरह से उदाहरण के लिए का एक टुकड़ा में परिवर्तित करने []byteके लिए [20]byteवास्तव में एक आवंटित करने के लिए है [20]byteका उपयोग करके जो आप कर सकते हैं var [20]byte(क्योंकि यह एक मूल्य है ... कोई makeजरूरत) और फिर इसे में डेटा की प्रतिलिपि:

buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)

अनिवार्य रूप से जो बहुत से अन्य उत्तर गलत मिलते हैं, वह []typeयह नहीं है कि एक सरणी है।

[n]Tऔर []Tपूरी तरह से अलग चीजें हैं!

जब []Tपरावर्तक प्रकार के ऐरे का नहीं होता है, लेकिन स्लाइस का [n]Tहोता है और दयालु एरे का होता है।

आप भी उपयोग map[[]byte]Tनहीं कर सकते, लेकिन आप उपयोग कर सकते हैंmap[[n]byte]T

यह कभी-कभी बोझिल हो सकता है क्योंकि बहुत सारे फ़ंक्शंस उदाहरण के लिए काम करते हैं []byteजबकि कुछ फ़ंक्शंस वापस [n]byte(सबसे विशेष रूप से हैश फ़ंक्शंस में crypto/*)। उदाहरण के लिए एक sha256 हैश है [32]byteऔर []byteऐसा नहीं है जब शुरुआती उदाहरण के लिए इसे एक फ़ाइल में लिखने की कोशिश करते हैं:

sum := sha256.Sum256(data)
w.Write(sum)

उन्हें एक त्रुटि मिलेगी। उपयोग करने का सही तरीका है

w.Write(sum[:])

हालाँकि, यह क्या है जो आप चाहते हैं? बस स्ट्रिंग तक पहुँचने? आप आसानी से एक stringका []byteउपयोग करने के लिए परिवर्तित कर सकते हैं :

bytes := []byte(str)

लेकिन यह एक सरणी नहीं है, यह एक टुकड़ा है। इसके अलावा; byte= rune। यदि आप "वर्ण" पर काम करना चाहते हैं, तो आपको उपयोग करने की आवश्यकता है rune... नहीं byte

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.