2016-08-24 5 views
1

Golangの文字列をループして、母音を含む単語とは別の単語を処理する方法を学ぶのが苦労しています。Goパニック:実行時エラー:インデックスが範囲外ですが配列の長さがnullではありません

私はここで、このコードスニペット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 

私はこのフォーラムで検索して、誰かがそれが配列の長さが原因だが、それはここではケースではありませんと言いました。私はこれを解決する方法を理解できません。 誰かが何か提案してもらえますか?ありがとう

答えて

1

長さが0で最大容量が4のスライスを作成しているが、同時に作成されたスライスの0番目のインデックスに値を割り当てようとしているという問題がある空の。このため、index out of range errorが届いています。容量は、スライスの長さと同じ長さになります意味

result := make([]string, 4) 

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

あなたがして、このコードを変更することができます。

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

あなたはおよそ配列スライスを読むことができるが、ここでをマップ:https://blog.golang.org/go-slices-usage-and-internals

+0

アスワンに感謝します!スライスについて知りませんでした – jiji

0

十分な長さのresultアレイを初期化していないため、インデックスの範囲外のエラーが表示されます。 myFunc

、あなたが持っている:

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

これは、長さ4の基本的な配列を持つ文字列のスライスを作成しませんが、あなたは0にスライス長を宣言しているため、基になる配列の要素のどれもスライスにアクセスできます。だからresult[0]も利用可能なインデックスの範囲外です。この問題を解決するには

、単にmakeに十分な大きさの長さのパラメータを指定する:

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

あなたはスライスがhereをどのように動作するかについての詳細を読むことができます。

+0

感謝を! – jiji

2

まず者に説明してみましょう:

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

make組み込み関数は、割り当てと初期化[]stringのオブジェクトは、Slicestring

Slice internals

A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment).

のでresult := make([]string, 0, 4)割り当て、length = 0capacity = 4とタイプ[]stringのオブジェクトを初期化します。
result := make([]string, 4, 4)は、タイプ[]stringのオブジェクトをlength = 4capacity = 4で割り振り、初期化します。これはresult := make([]string, 4)に等しくなります。ランタイムエラー:範囲外のインデックスresult := make([]string, 0, 4)このスライスの下にある配列パニックになるresult[0]を使用して空の意味があると

は今result := make([]string, 0, 4)result := make([]string, 4)の違いは何です。

result := make([]string, 4)と、このスライスはresult[0]を用い意味4つのstring要素、result[1]result[2]result[3]がOKである持っているの基礎となる配列:

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{"", "", "", ""}このコードの意味:

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

"", "", "", "" 

The append built-in function appends elements to the end of a slice. If it has sufficient capacity, the destination is resliced to accommodate the new elements. If it does not, a new underlying array will be allocated. Append returns the updated slice. It is therefore necessary to store the result of append, often in the variable holding the slice itself:

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

As a special case, it is legal to append a string to a byte slice, like this:

slice = append([]byte("hello "), "world"...) 
機能 myFunc内部コードで今すぐ

は、あなたがこの作業コードのように、appendを使用することがあります:3210

package main 

import "fmt" 

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

出力は、上記のコードと同じです):

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 
} 

あなたは、この作業コード(The Go Playground)のように、そのコードを簡素化することがあります。aswerため

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 
} 
+0

@jijiこれが役立つことを願っています。 –

+0

あなたの答えと 'append'についての説明をありがとう。私は、配列の最後に追加するのではなく、同じ配列を使っていくつかの並べ替えをしたいので、追加することなくそれを行うのが私の場合にはもっと便利だと思います。 – jiji

関連する問題