jjzjj

go - http.ResponseWriter.Write 接口(interface){}

coder 2024-07-09 原文

我正在使用 denisenkom 中的示例运行 SQL 查询但再加上 http.ResponseWriter,我正在为 interface{} 类型转换而苦苦挣扎。有一些帖子与我正在做的很接近,但解决方案似乎有点笨拙,并且总是使用 fmt(我没有使用)。

请注意,我的查询有效并返回结果。我只是想显示该结果。

这是我认为比较接近但不起作用的代码。我尝试了其他一些东西,但都没有编译。

vals := make([]interface{}, len(cols))
for i := 0; i < len(cols); i++ {
        vals[i] = new(interface{})
        if i != 0 {
                w.Write([]byte("\t"))
        }
        w.Write([]byte(cols[i]))
}

for rows.Next() {
      err = rows.Scan(vals...)
      if err != nil {
          w.Write([]byte("Row problem: " + err.Error()))
          continue
      }
      for i := 0; i < len(vals); i++ {
          if i != 0 {
              w.Write([]byte("\t"))
          }

      //THIS IS THE PART I'M STUCK ON       
      switch v := vals[i].(type) {
      case int:
           w.Write([]byte("int!\n" + string(v)))
      case int8:
           w.Write([]byte("int8!\n" + string(v)))

      //etc, etc
      //more types
      //etc, etc

      case float64:
           w.Write([]byte("float64!\n" + string(v))) //This fails, can't convert, will need something else
      case string:
           w.Write([]byte("string!\n" + v))
      default:
           w.Write([]byte("something else!\n"))
      }
  }

}

但是没有更好的方法来动态检查底层类型并将其转换为可读的东西吗?我只想吐出查询的结果,这似乎是我做错了什么。

请注意,它总是符合 default 的情况,即使它是明确相同的类型也是如此。

最佳答案

denisekom 处的示例使用 fmt.Print 系列函数打印到标准输出。更改示例以使用 fmt.Fprint 函数系列打印到响应编写器。

fmt.Fprint 函数写入指定为第一个参数的 io.Writer。响应编写器满足 io.Writer 接口(interface)。这是原始示例的修改代码,其中 w 是 http.ResponseWriter。

vals := make([]interface{}, len(cols))
for i := 0; i < len(cols); i++ {
    vals[i] = new(interface{})
    if i != 0 {
        fmt.Fprint(w, "\t")
    }
    fmt.Fprint(w, cols[i])
}
fmt.Fprintln(w)
for rows.Next() {
    err = rows.Scan(vals...)
    if err != nil {
        fmt.Fprintln(w, err)
        continue
    }
    for i := 0; i < len(vals); i++ {
        if i != 0 {
            fmt.Fprint(w, "\t")
        }
        printValue(w, vals[i].(*interface{}))
    }
    fmt.Fprintln(w)

}

... 

func printValue(w io.Writer, pval *interface{}) {
    switch v := (*pval).(type) {
    case nil:
        fmt.Fprint(w, "NULL")
    case bool:
        if v {
            fmt.Fprint(w, "1")
        } else {
            fmt.Fprint(w, "0")
        }
    case []byte:
        fmt.Fprint(w, string(v))
    case time.Time:
        fmt.Fprint(w, v.Format("2006-01-02 15:04:05.999"))
    default:
        fmt.Fprint(w, v)
    }
}

关于问题中的代码:表达式string(v)是一个字符串转换。字符串转换不会像代码假设的那样将数字转换为十进制表示形式。查看spec有关字符串转换的详细信息。使用上面的 fmt 包或 strconv 包将数字转换为十进制字符串。类型开关应该是 switch v := (*(vals[i].(*interface{})).(type) {。这有点乱,这引出了我的下一个观点.

原始示例使用了比需要更多的间接。这是一个简化的版本,可以通过响应编写器调用:

func exec(w io.Writer, db *sql.DB, cmd string) error {
    rows, err := db.Query(cmd)
    if err != nil {
        return err
    }
    defer rows.Close()
    cols, err := rows.Columns()
    if err != nil {
        return err
    }
    if cols == nil {
        return nil
    }
    vals := make([]interface{}, len(cols))
    args := make([]interface{}, len(cols))
    for i := 0; i < len(cols); i++ {
        args[i] = &vals[i]
        if i != 0 {
            fmt.Fprint(w, "\t")
        }
        fmt.Fprint(w, cols[i])
    }
    for rows.Next() {
        err = rows.Scan(args...)
        if err != nil {
            fmt.Fprintln(w, err)
            continue
        }
        for i := 0; i < len(vals); i++ {
            if i != 0 {
                fmt.Print("\t")
            }
            printValue(w, vals[i])
        }
        fmt.Fprintln(w)

    }
    if rows.Err() != nil {
        return rows.Err()
    }
    return nil
}

func printValue(w io.Writer, v interface{}) {
    switch v := v.(type) {
    case nil:
        fmt.Fprint(w, "NULL")
    case bool:
        if v {
            fmt.Fprint(w, "1")
        } else {
            fmt.Fprint(w, "0")
        }
    case []byte:
        fmt.Fprint(w, string(v))
    case time.Time:
        fmt.Fprint(w, v.Format("2006-01-02 15:04:05.999"))
    default:
        fmt.Fprint(w, v)
    }
}

关于go - http.ResponseWriter.Write 接口(interface){},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47662614/

有关go - http.ResponseWriter.Write 接口(interface){}的更多相关文章

  1. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  2. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  3. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  6. ruby-on-rails - Heroku 吃掉了我的自定义 HTTP header - 2

    我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份​​验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby​​脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara

  7. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

    我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

  8. ruby - HTTP 请求中的用户代理,Ruby - 2

    我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)

  9. ruby - 如何使用 Ruby HTTP::Net 处理 404 错误? - 2

    我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。

  10. ruby - 让 bundler 使用 http : instead of git:? - 2

    我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://

随机推荐