リフレクションを使用した Scan() 可変個引数関数の呼び出し
Rows.Scan() 関数は、データベースからデータを取得する便利な方法を提供しますクエリ。ただし、可変数のポインターを引数として利用するため、リフレクションを使用して組み込むのは困難な場合があります。 次のシナリオを考えてみましょう:
クエリから取得した値をスライスに動的に設定し、Rows.Scan() を利用してデータを抽出したいと考えています。この場合、列の数を決定し、値を保存するスライスを作成する必要があります。
よくある落とし穴:
リフレクションを使用して、 Scan() 関数は予期しない結果を引き起こす可能性があります。これは、Rows.Scan() が値へのポインタを想定しており、単純にインターフェース値のスライスを渡すと nil 参照が発生するためです。
解決策:
リフレクションを使用して Scan() を正常に呼び出すには、デュアル スライス アプローチが採用されます。最初のスライス、values には実際のデータが保持され、2 番目のスライス、valuesPtrs には、values の各要素へのポインターが含まれます。
クエリ結果の各列について、valuesPtrs のポインターは対応する要素にマップされます。価値観において。その後、valuesPtrs を引数として Rows.Scan() を呼び出し、効果的に値を入力します。
作業例:
package main import ( "fmt" _ "github.com/lib/pq" "database/sql" ) func main() { db, _ := sql.Open( "postgres", "user=postgres dbname=go_testing password=pass sslmode=disable") rows, _ := db.Query("SELECT * FROM _user;") columns, _ := rows.Columns() count := len(columns) values := make([]interface{}, count) valuesPtrs := make([]interface{}, count) for rows.Next() { for i := range columns { valuesPtrs[i] = &values[i] } rows.Scan(valuesPtrs...) for i, col := range columns { val := values[i] b, ok := val.([]byte) var v interface{} if (ok) { v = string(b) } else { v = val } fmt.Println(col, v) } } }
この例では、行です。 Scan() はポインタ スライス valuePtrs を使用して呼び出され、取得したデータを値スライスに設定します。次に、ループは各列名とそれに対応する値を出力します。
以上がリフレクションを使用してデータベース/SQL Rows.Scan() 可変個引数関数を呼び出す方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。