草庐IT

Golang 标准包结构

coder 2024-07-07 原文

我是 Go 的新手,我正在尝试使用 Ben Johnson 网页的指导创建结构化应用程序。不幸的是,他的示例并不是一个完整的工作应用程序。

他的网页是https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1

我尝试使用他的方法,但我不断收到“Undefined: db”错误。它没有告诉我是哪一行导致了错误,只是告诉我文件“MSSQL.go”

有人可以提供指导以帮助我修复此错误吗?

使用可接受的解决方案编辑代码。

StatementPrinter.go

    package statementprinter

    type Statement struct {
      CustomerId   string
      CustomerName string
    }

    type StatementService interface {
      Statement(id string) (*Statement, error)
    }

main.go

            package main

            import (
              "fmt"
              "log"
              "github.com/ybenjolin/StatementPrinter"
              "github.com/ybenjolin/StatementPrinter/mssql"
              "database/sql"
              _ "github.com/alexbrainman/odbc"
            )

            const DB_INFO = "Driver={SQL Server};Server=cdc-edb2;Database=CostarReports;Trusted_Connection=yes;"

            var db *sql.DB

            func init() {
              var err error
              db, err = sql.Open("odbc", DB_INFO)
              if err != nil {
                log.Fatal("Error opening database connection.\n", err.Error())
              }
              err = db.Ping()
              if err != nil {
                log.Fatal("Error pinging database server.\n", err.Error())
              }
              fmt.Println("Database connection established.")
            }

            func main () {
              var err error
              defer db.Close()

              // Create services
              // Changes required here. Was ss := &statementprinter.Stat..
              ss := &mssql.StatementService{DB: db}

              // Use service
              var s *statementprinter.Statement
              s, err = ss.Statement("101583")
              if err != nil {
                log.Fatal("Query failed:", err.Error())
              }
              fmt.Printf("Statement: %+v\n", s)
            }

mssql.go

    package mssql  

    import (
      _ "github.com/alexbrainman/odbc"
      "database/sql"
      "github.com/ybenjolin/StatementPrinter"
    )

    // StatementService represents a MSSQL implementation of statemenetprinter.StatementService.
    type StatementService struct {
      DB *sql.DB
    }

    // Statement returns a statement for a given customer.
    func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
      var err error
      var t statementprinter.Statement
      // Changes required here. Was row := db.Query......
      row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
      if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
        return nil, err
      }
      return &t, nil

最佳答案

这似乎只是一个错字。似乎有问题的行在方法中

 func (s *StatementService) Statement(customer string) 

在 mssql.go 中,

  row := db.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)

QueryRow 应该是db 的一个方法,但是db 没有定义。然而,在结构中

type StatementService struct {
  DB *sql.DB
}

有一个*sql.DB 实例。您使用的方法有一个 *StatementService 参数,s。所以,我的猜测是打算像这样访问 s 中的 sql.DB 字段

func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
  var err error
  var t statementprinter.Statement
   //CHANGED LINE:
  row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
  if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
    return nil, err
  }
  return &t, nil

然后,在 main.go 中调用该方法,并传递一个包含数据库的 StatementService 实例:

ss := &statementprinter.StatementService{DB: db}

我相信你需要把这一行改成

ss := &mssql.StatementService{DB: db}

因为这是实际的接口(interface)实现。您现在拥有的行将 StatementService 接口(interface)视为无法编译的结构。 main.go 中的全局 db 在应用程序的生命周期内存在。它只是一个被复制以供使用的指针。

关于Golang 标准包结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48431359/

有关Golang 标准包结构的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  3. ruby - 将 spawn() 的标准输出/标准错误重定向到 Ruby 中的字符串 - 2

    我想使用spawn(针对多个并发子进程)在Ruby中执行一个外部进程,并将标准输出或标准错误收集到一个字符串中,其方式类似于使用Python的子进程Popen.communicate()可以完成的操作。我尝试将:out/:err重定向到一个新的StringIO对象,但这会生成一个ArgumentError,并且临时重新定义$stdxxx会混淆子进程的输出。 最佳答案 如果你不喜欢popen,这是我的方法:r,w=IO.pipepid=Process.spawn(command,:out=>w,:err=>[:child,:out])

  4. ruby-on-rails - 标准化文件名的字符串,删除重音和特殊字符 - 2

    我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin

  5. ruby-on-rails - 一般建议和推荐的文件夹结构 - Sinatra - 2

    您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应

  6. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

    我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

  7. Ruby:标准递归模式 - 2

    我经常迷上ruby​​的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情

  8. ruby-on-rails - 使用 Ruby 标准 Logger 每天只创建一个日志 - 2

    我正在使用ruby​​标准记录器,我想要每天轮换一次,所以在我的代码中我有:Logger.new("#{$ROOT_PATH}/log/errors.log",'daily')它运行完美,但它创建了两个文件errors.log.20130217和errors.log.20130217.1。如何强制它每天只创建一个文件? 最佳答案 您的代码对于长时间运行的应用程序是正确的。发生的事情是您在给定的一天多次运行代码。第一次运行时,Ruby会创建一个日志文件“errors.log”。当日期改变时,Ruby将文件重命名为“errors.log

  9. ruby-on-rails - 在 Rails 中存储(结构化)配置数据的位置 - 2

    对于我正在编写的Rails3应用程序,我正在考虑从本地文件系统上的XML、YAML或JSON文件中读取一些配置数据。重点是:我应该把这些文件放在哪里?Rails应用程序中是否有用于存储此类内容的默认位置?附带说明一下,我的应用程序部署在Heroku上。 最佳答案 我经常做的是:如果文件是通用配置文件:我在目录/config中创建一个YAML文件,每个环境有一个上层key如果我为每个环境(大项目)创建一个文件:我为每个环境创建一个YAML并将它们存储在/config/environments/然后我在加载YAML的地方创建了一个初始化

  10. 用于从 Open3.popen3 标准输出中提取值的正则表达式 - 2

    如何获取外部命令的输出并从中提取值?我有这样的东西:stdin,stdout,stderr,wait_thr=Open3.popen3("#{path}/foobar",configfile)if/exit0/=~wait_thr.value.to_srunlog.puts("Foobarexitednormally.\n")puts"Testcompleted."someoutputvalue=stdout.read("TX.*\s+(\d+)\s+")puts"Outputvalue:"+someoutputvalueend我没有在标准输出上使用正确的方法,因为Ruby告诉我它不能

随机推荐