2017-02-16 13 views
2

Я новичок в Golang и скомпилирован, статически типизировал программирование в целом. Весь мой предыдущий опыт был с Python.Голан, указатели, функции

Этот сдвиг парадигмы был как разочаровывающим (программы редко компилируются), так и вознаграждением, так как я, наконец, обдумываю многие концепции, которые ранее были чужды мне (сбор мусора, указатели, область действия).

Может кто-нибудь объяснить мне концептуальный уровень, почему эта программа не будет компилироваться и синтаксис исправить? Я просто пытаюсь сделать запрос к БД и распечатать результаты:

package main 

import (
    "database/sql" 
    "log" 

    _ "github.com/denisenkom/go-mssqldb" 
) 

func main() { 

    db, err := sql.Open("sqlserver", "odbc:server=myServer;user id=myName;password=myPassword;") 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer db.Close() 

    q() 
} 

func q() { 

    var (
     id int 
     name string 
    ) 

    rows, err := db.Query("SELECT id, name FROM myTable") 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer rows.Close() 

    for rows.Next() { 
     err := rows.Scan(&id, &name) 

     if err != nil { 
      log.Fatal(err) 
     } 
     log.Println(id, name) 
    } 
    err = rows.Err() 
    if err != nil { 
     log.Fatal(err) 
    } 

} 

Ошибка я получаю:

undefined: db in db.Query

Запрос работает, когда я ставлю логику внутри д() в основной функции - я предполагаю, что это потому, что функции имеют «локальную» область (это правильная терминология?), и мне нужно определить объект db, как у меня в основной функции.

Если это так - как запустить функцию q(), не повторяя при установлении соединения db? Это где «указатели» входят? Кроме того, я до сих пор уверен в том, что делают здесь амперсанды:

err := rows.Scan(&id, &name) 

Благодарность

+1

как о прохождении 'db' в качестве аргумента' д() '? это сработает. –

+0

Это также не работает с правилами определения python, вы определили 'db' в' main', но пытаетесь ссылаться на него в 'q'. – JimB

+0

Связанный: https://stackoverflow.com/questions/40587008/how-do-i-handle-opening-closing-db-connection-in-a-go-app – JimB

ответ

3

db вар определяется в main Func сферы, так что ваш q функ «не видит» его. Вы должны передать указатель на метод q. Нечто подобное:

func q(db *sql.DB) { 
    ... 
} 

Ваш db вар в main уже указатель на sql.DB структуры, так что вы просто должны сделать q(db) вызов в main FUNC, и он будет работать.

+1

Продолжайте! Вы делаете хорошо! Go - это новый мир для вас, так что это нормально, чтобы запутаться при первых попытках. –

+1

. Пожалуйста, оставьте слово «reference»: в Go нет ссылок. – kostix

2

Как уже упоминалось, проблема в переменной db объявлена ​​в функции main, и вы пытаетесь получить доступ к этой переменной в функции q. У вас есть два варианта решения этой проблемы:

1) Объявляем переменную db как глобальную переменную вне основной функции, как это:

Как и другие упоминали, проблема переменная db объявлена ​​в функции main и вы пытаетесь получить доступ к этой переменной в функции q. У вас есть два варианта решения этой проблемы:

1) Объявляем переменную db как глобальную переменную вне основной функции, как это:

package main 

import (
"database/sql" 
"log" 
_ "github.com/denisenkom/go-mssqldb" 
) 

var db *sql.DB 

func main() { 

db, err = sql.Open("sqlserver", "odbc:server=myServer;user id=myName;password=myPassword;") 
. 
. 
. 
. 

Важно заметить это назначение (= вместо :=), используемый для присвоения значения глобальной переменной. Потому что, если вы используете короткую переменную declare :=, она создаст локальную переменную db.

2) Вы можете передать db указатель в качестве параметра функции q так:

package main 

import (
    "database/sql" 
    "log" 
    _ "github.com/denisenkom/go-mssqldb" 
) 
func main() { 

    db, err := sql.Open("sqlserver", "odbc:server=myServer;user id=myName;password=myPassword;") 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer db.Close() 

    q(db) 
} 

func q(db *sql.DB) { 

    var (
     id int 
     name string 
    ) 
. 
. 
. 
. 

 Смежные вопросы

  • Нет связанных вопросов^_^