83

Goで複数の戻り値をキャストする慣用的な方法は何ですか?

1行で実行できますか、それとも以下の例で行ったような一時変数を使用する必要がありますか?

package main

import "fmt"

func oneRet() interface{} {
    return "Hello"
}

func twoRet() (interface{}, error) {
    return "Hejsan", nil
}

func main() {
    // With one return value, you can simply do this
    str1 := oneRet().(string)
    fmt.Println("String 1: " + str1)

    // It is not as easy with two return values
    //str2, err := twoRet().(string) // Not possible
    // Do I really have to use a temp variable instead?
    temp, err := twoRet()
    str2 := temp.(string)
    fmt.Println("String 2: " + str2 )


    if err != nil {
        panic("unreachable")
    }   
}

ちなみに、castingインターフェースに関しては呼ばれていますか?

i := interface.(int)
4

4 に答える 4

72

1行ではできません。あなたの一時変数アプローチは行くべき道です。

ところで、インターフェースのことをキャストと言いますか?

これは実際には型アサーションと呼ばれます。型キャスト変換は異なります。

var a int
var b int64

a = 5
b = int64(a)
于 2012-07-09T21:26:53.207 に答える
39
func silly() (interface{}, error) {
    return "silly", nil
}

v, err := silly()
if err != nil {
    // handle error
}

s, ok := v.(string)
if !ok {
    // the assertion failed.
}

しかし、実際に必要なのは、次のようなタイプ スイッチを使用することです。

switch t := v.(type) {
case string:
    // t is a string
case int :
    // t is an int
default:
    // t is some other type that we didn't name.
}

Go は簡潔さよりも正確さを重視します。

于 2012-07-20T13:40:16.773 に答える
18

または、単一の場合:

if v, ok := value.(migrater); ok {
    v.migrate()
}

Go は if 句内のキャストを処理し、キャストされた型のプロパティにアクセスできるようにします。

于 2017-03-09T10:53:39.980 に答える
12

template.Mustは、1つのステートメントで最初の戻り値のみを返すための標準ライブラリのアプローチです。あなたの場合も同様に行うことができます:

func must(v interface{}, err error) interface{} {
    if err != nil {
        panic(err)
    }
    return v
}

// Usage:
str2 := must(twoRet()).(string)

あなたを使用することによりmust、基本的にエラーは発生しないはずであり、エラーが発生した場合、プログラムは動作を継続できず(または少なくとも動作し続けるべきではなく)、代わりにパニックになります。

于 2012-07-09T21:39:52.087 に答える