বাইট অ্যারেতে স্ট্রিং কীভাবে নির্ধারণ করা যায়


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যখন বাইট একটি স্ট্রিং রূপান্তর হচ্ছে ... আমাকে বিশ্বাস কর না? এই থ্রেডে
ওপেনওনক

9
ওপি একটি স্লাইস নয়, একটি অ্যারের সম্পর্কে জিজ্ঞাসা করেছিল। কিছু ক্ষেত্রে আপনাকে স্লাইসের আকার সীমাবদ্ধ করতে হবে এবং তার পরিবর্তে একটি অ্যারে ব্যবহার করা উচিত। নীচে আমার উত্তরটি অতিরিক্ত অক্ষর ছাঁটাই করে তা নিশ্চিত করে নিন যে আপনি অ্যারে উপচে পড়ছেন না।
ডেভিডজি

3
যারা এটিকে কিছুটা অদ্ভুত বলে মনে করেন তাদের জন্য: এটি গো: golang.org/ref/spec#Cversvers- এ
Cnly

একাধিক স্ট্রিং যুক্ত করার এবং সেগুলি সংযুক্ত করার কোনও উপায়? যেমন []byte("one", "two")?
রকিম

দুর্ভাগ্যক্রমে না, @ রকিম, আপনি কেবল একটি স্ট্রিং পাশ করতে পারবেন ... সুতরাং, আপনাকে প্রথমে তাদেরকে সম্মতি জানাতে হবে বা একাধিক বাইটের স্লাইসগুলি (এই প্রশ্নের বাইরের ক্ষেত্রের) একত্রিত করতে হবে।
ওপেনওনক

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, The অনুলিপি ফাংশন বোবা হয় না। স্লাইসগুলিতে অনুলিপি করা এবং অনুলিপি করা : "অনুলিপি করা উপাদানগুলির সংখ্যা হ'ল ন্যূনতম (এসসিআর) এবং লেন (ডিএসটি)" "
পিটারসো

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)))
}

আউটপুট:

[104 101 108 108 111 32 119 111 114 108 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বিশেষ সংকলক সমর্থন রয়েছে, সুতরাং এটি বিভিন্ন ধরণের আর্গুমেন্ট পরিচালনা করতে পারে এবং এটি সম্ভবত কভারগুলির নিচে সত্যিই উচ্চ-কার্যকারিতা বাস্তবায়ন করে। এছাড়াও, ওপির প্রশ্নটিতে একটি নতুন বরাদ্দকরণের পরিবর্তে একটি বিদ্যমান অ্যারেতে স্ট্রিং লেখার বিষয়ে জিজ্ঞাসা করা হয়েছিল, যদিও অন্যান্য উত্তরগুলির বেশিরভাগ উত্তরও সেটিকে উপেক্ষা করছে বলে মনে হচ্ছে ...
জ্যাক ও'কনর

ধন্যবাদ @ জ্যাকও'কনর আমি শেখার জন্যও এখানে আছি এবং গঠনমূলক প্রতিক্রিয়ার প্রশংসা করি, কেবল সরল ডাউনওয়েট নয়।
ডেভিডজি

জানেন না যে তার ডাউন ভোট 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)পদ্ধতির চেয়ে দ্বিগুণ-অনিরাপদ পছন্দ করবেন তা নিশ্চিত নন ।
টমাসজ

1
@ টমাসজ আমি এইভাবে স্ট্রিং </> [] বাইট করতে পছন্দ করি না, কেবল একটি ভিন্ন বিকল্প দেখায় :-) এবং হ্যাঁ আপনি ঠিক বলেছেন, আমি প্রশ্নটি ভুল বুঝেছি।
ব্র্যান্ডন গাও

যখন আমি এটি করি, cap()ফলাফলটির একটি স্বেচ্ছাসেবী আকার থাকে যার অর্থ এটি অজানা স্মৃতিতে পড়া reading এটি ঠিক হওয়ার জন্য, আমি মনে করি আপনার অবশ্যই পুরো reflect.SliceHeaderআকারটি বরাদ্দ করা উচিত এবং ম্যানুয়ালি সেটটি করা দরকার cap। এরকম কিছু: play.golang.org/p/fBK4dZM-qD
লাই ফিশ

আর আমি যে এমনকি নির্দিষ্ট নই .------------- ^ - হয়তো এই উত্তম: play.golang.org/p/NJUxb20FTG
লাই মাছ

-1

অ্যারেগুলি হ'ল মান ... স্লাইসগুলি পয়েন্টারের মতো are এটি মূলত দুটি ভিন্ন জিনিস হওয়ায় এটির [n]typeসাথে সামঞ্জস্য নেই []type। আপনি একটি স্লাইস পেতে পারেন arr[:]যা একটি অ্যারে নির্দেশ করে এমন একটি স্লাইস দেয় যা ব্যবহার করে rayarr সমর্থন করছে।

ওয়ান ওয়ে উদাহরণস্বরূপ একটি ফালি রূপান্তর করতে []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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.