web-dev-qa-db-ja.com

Goでスライスに特定のインデックスがあるかどうかを確認するにはどうすればよいですか?

地図で簡単にできます:

item, ok := myMap["index"]

しかしスライスではありません:

item, ok := mySlice[3] // panic!

これは以前に尋ねられなかったことに驚いた。たぶん私はGoスライスで間違ったメンタルモデルを使っていますか?

29
marcio

Goにはスパーススライスがないため、単純に長さを確認できます。

if len(mySlice) > 3 {
    // ...
}

長さが3より大きい場合は、インデックス3およびそれより前のインデックスがすべて存在することがわかります。

24
laurent

Ifステートメントの使用は、ソースコードの読み取りを困難にするため、私は嫌いです。よりエレガントな方法は、switch/caseを使用することです。スイッチ/ケースは非常に多機能なGoにあるため、この投稿のすべての回答を読んだ後、次の解決策を思いつきました:

package main

import (
    "fmt"
)

func checkarg(data ...string) {
    for _, value := range data {
        fmt.Printf("<%v> ", value)
    }
    fmt.Println()
    switch len(data) {
    case 0:
        fmt.Println("No arguments at all!")
        fmt.Println("Missing <IP:port>")
        fallthrough
    case 1:
        fmt.Println("Missing <command>")
        fallthrough
    case 2:
        fmt.Println("Missing <key>")
        fallthrough
    case 3:
        fmt.Println("Missing <value>")
    case 4:
        fmt.Println("len = 4 (correct)")
    default:
        fmt.Println("Unknown length")
    }
}

func main() {
    checkarg("127.0.0.1:6379", "set", "Foo", "Bar", "test")
    fmt.Println()
    checkarg("127.0.0.1:6379", "set", "Foo", "Bar")
    fmt.Println()
    checkarg("127.0.0.1:6379", "set", "Foo")
    fmt.Println()
    checkarg("127.0.0.1:6379", "set")
    fmt.Println()
    checkarg("127.0.0.1:6379")
    fmt.Println()
    checkarg()
    fmt.Println()
}

出力:

<127.0.0.1:6379> <set> <Foo> <Bar> <test>
Unknown length

<127.0.0.1:6379> <set> <Foo> <Bar>
len = 4 (correct)

<127.0.0.1:6379> <set> <Foo>
Missing <value>

<127.0.0.1:6379> <set>
Missing <key>
Missing <value>

<127.0.0.1:6379>
Missing <command>
Missing <key>
Missing <value>


No arguments at all!
Missing <IP:port>
Missing <command>
Missing <key>
Missing <value>

それはあなたの問題とまったく同じではありませんが、これはそれを回避する方法のアイデアをあなたに与えるためだけです。

0
Dippo