मुझे कुछ चीजें करने के लिए गो में एक स्ट्रिंग के माध्यम से लूप करना सीखने में कठिनाई हो रही है (विशेष रूप से, स्वरों को अलग करने के लिए शब्दों को अलग करने के लिए)।

मैंने यह कोड स्निपेट लिखा है: https://play.golang.org/p/zgDtOyq6qf

इसे चलाते समय मुझे जो त्रुटि मिल रही है वह यहां दी गई है:

panic: runtime error: index out of range

goroutine 1 [running]:
panic(0x1045a0, 0x1040a010)
    /usr/local/go/src/runtime/panic.go:500 +0x720
main.myFunc(0x114130, 0x4, 0x0, 0x0, 0x0, 0x3ba3)
    /tmp/sandbox960520145/main.go:19 +0x1a0
main.main()
    /tmp/sandbox960520145/main.go:10 +0x40

मैंने इस फ़ोरम में खोजा, और किसी ने कहा कि यह सरणी की लंबाई के कारण है, लेकिन यहाँ ऐसा नहीं है। मैं यह नहीं समझ सकता कि इस मुद्दे को कैसे हल किया जाए। क्या कोई कृपया कुछ सुझा सकता है?

7
jiji 24 अगस्त 2016, 12:05

3 जवाब

सबसे बढ़िया उत्तर

मुद्दा यह है कि आप लंबाई 0 के साथ एक स्लाइस बना रहे हैं, लेकिन 4 की अधिकतम क्षमता के साथ, लेकिन साथ ही आप पहले से ही बनाए गए स्लाइस के ज़ीरोथ इंडेक्स के लिए एक मान आवंटित करने का प्रयास कर रहे हैं। , जो आमतौर पर खाली होता है। यही कारण है कि आप index out of range error प्राप्त कर रहे हैं।

result := make([]string, 0, 4)
fmt.Println(len(result)) //panic: runtime error: index out of range

आप इस कोड को इसके साथ बदल सकते हैं:

result := make([]string, 4)

जिसका अर्थ है कि क्षमता स्लाइस की लंबाई के समान ही होगी।

fmt.Println(cap(result)) // 4
fmt.Println(len(result)) // 4

आप यहां सरणी, स्लाइस और मानचित्र के बारे में पढ़ सकते हैं: https://blog.golang.org/go-slices-usage-and-internals

2
Endre Simo 24 अगस्त 2016, 12:48
उत्तर के लिए धन्यवाद! slices के बारे में नहीं जानता था
 – 
jiji
24 अगस्त 2016, 13:10

आइए पहले समझाते हैं:

result := make([]string, 0, 4)

मेक बिल्ट-इन फंक्शन []string प्रकार के ऑब्जेक्ट को आवंटित और इनिशियलाइज़ करता है। Slice में से string

स्लाइस इंटर्नल:

एक टुकड़ा एक सरणी खंड का एक विवरणक है। इसमें सरणी के लिए एक सूचक, खंड की लंबाई और इसकी क्षमता (खंड की अधिकतम लंबाई) शामिल है।

तो result := make([]string, 0, 4) []string प्रकार की किसी वस्तु को length = 0 और capacity = 4 के साथ आवंटित और प्रारंभ करता है।
और result := make([]string, 4, 4) []string के साथ length = 4 और capacity = 4, जो result := make([]string, 4) के बराबर है, की एक वस्तु आवंटित और आरंभ करता है।

अब result := make([]string, 0, 4) और result := make([]string, 4) में क्या अंतर है:

result := make([]string, 0, 4) के साथ इस स्लाइस की अंतर्निहित सरणी खाली है result[0] का उपयोग करने से घबराहट होगी: रनटाइम त्रुटि: सीमा से बाहर अनुक्रमणिका।

result := make([]string, 4) के साथ इस स्लाइस की अंतर्निहित सरणी में 4 string तत्व हैं, जिसका अर्थ है result[0], result[1], result[2], result[3] का उपयोग करना ठीक है:

package main

import "fmt"

func main() {
    result := make([]string, 4)
    fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])
}

आउटपुट:

"", "", "", "" 

और result := make([]string, 4), result := []string{"", "", "", ""} के बराबर है, जिसका अर्थ है यह कोड:

package main

import "fmt"

func main() {
    result := []string{"", "", "", ""}
    fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])
}

आउटपुट उपरोक्त कोड के समान है:

"", "", "", "" 

अंतर्निहित फ़ंक्शन संलग्न करें तत्वों को एक स्लाइस के अंत में जोड़ता है। यदि उसके पास पर्याप्त क्षमता है, नए तत्वों को समायोजित करने के लिए गंतव्य को हटा दिया गया है। अगर यह नहीं, एक नई अंतर्निहित सरणी आवंटित की जाएगी। परिशिष्ट देता है अद्यतन टुकड़ा। इसलिए परिणाम को संग्रहीत करना आवश्यक है संलग्न करें, अक्सर स्लाइस को पकड़े हुए चर में:

slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)

एक विशेष मामले के रूप में, एक स्ट्रिंग को बाइट स्लाइस में जोड़ना कानूनी है, जैसे:

slice = append([]byte("hello "), "world"...)

अब आपके कोड में फ़ंक्शन myFunc के बाद result := make([]string, 0, 4) के बाद, आप append का उपयोग कर सकते हैं, जैसे यह कार्यशील कोड (द गो प्लेग्राउंड):

package main

import (
    "fmt"
    "strings"
)

func main() {
    strs := strings.Fields("Political srt")
    fmt.Println(len(strs)) // It's not empty so why index out of range
    fmt.Println(strs, strs[0], strs[1])
    fmt.Println(strings.ContainsAny(strs[0], "eaiuo"))
    fmt.Println(myFunc("Political srt"))
}

func myFunc(input string) []string {
    strs := strings.Fields(input)
    result := make([]string, 0, 4)
    for i := 0; i < len(strs); i++ {
        if strings.ContainsAny(strs[i], "eaiu") {
            result = append(result, strs[i])
        } else {
            result = append(result, strs[i])
        }
    }
    return result
}

आप उस कोड को सरल बना सकते हैं, जैसे यह कार्यशील कोड (द गो प्लेग्राउंड):

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(myFunc("Political srt"))
}

func myFunc(input string) []string {
    strs := strings.Fields(input)
    result := make([]string, 0, 4)
    for _, s := range strs {
        if strings.ContainsAny(s, "eaiu") {
            result = append(result, s)
        }
    }
    return result
}
12
13 सितंबर 2016, 15:21
आशा है कि ये आपकी मदद करेगा।
 – 
user6169399
24 अगस्त 2016, 14:01
आपके उत्तर और append के बारे में स्पष्टीकरण के लिए धन्यवाद। मुझे लगता है कि यह मेरे मामले में परिशिष्ट के बिना करने के लिए और अधिक उपयोगी है क्योंकि मैं सरणी के अंत में जोड़ने के बजाय उसी सरणी का उपयोग करके कुछ ऑर्डर करना चाहता हूं।
 – 
jiji
25 अगस्त 2016, 16:18

अनुक्रमणिका सीमा से बाहर त्रुटि दिखाई दे रही है क्योंकि आप result सरणी को पर्याप्त लंबाई के साथ प्रारंभ नहीं कर रहे हैं।

myFunc में, आपके पास:

result := make([]string, 0, 4)

यह स्ट्रिंग्स का एक टुकड़ा बनाता है जिसमें लंबाई 4 की अंतर्निहित सरणी होती है, लेकिन चूंकि आपने स्लाइस की लंबाई 0 घोषित की है, अंतर्निहित सरणी से कोई भी तत्व स्लाइस तक पहुंच योग्य नहीं है। तो result[0] भी उपलब्ध सूचकांकों की सीमा से बाहर है।

इसे ठीक करने के लिए, बस make को पर्याप्त रूप से बड़े लंबाई के पैरामीटर की आपूर्ति करें:

result := make([]string, 4, 4)

आप इस बारे में अधिक पढ़ सकते हैं कि स्लाइस कैसे काम करते हैं यहां

1
abhink 24 अगस्त 2016, 12:10
उत्तर के लिए धन्यवाद!
 – 
jiji
24 अगस्त 2016, 12:59