How do I extract a string from an interface{} variable in Go?

huangapple go评论77阅读模式
英文:

How do I extract a string from an interface{} variable in Go?

问题

我对Go语言还不熟悉。

我正在使用Go、Gorilla工具包和Mustache模板引擎制作一个小型的Web应用程序。

到目前为止一切都很顺利。

我使用了hoisie/mustache和gorilla/sessions,但是我在将变量从一个地方传递到另一个地方时遇到了困难。我有一个map[string]interface{},我将其传递给模板引擎。当用户登录时,我想将用户的会话数据与我的map[string]interface{}合并,以便可以在渲染时使用这些数据。

问题是gorilla/sessions返回的是一个map[interface{}]interface{},所以无法进行合并(根据我在这门语言上的技能)。

我考虑过提取interface{}变量中的字符串(使用反射?)。
我还考虑过将我的会话数据设置为map[interface{}]interface{},就像gorilla/sessions提供的那样。但是作为一个Java程序员,我觉得使用Object类型的变量更方便。

我想知道在你看来,这个问题的最佳解决方案是什么。

提前感谢你的帮助。

英文:

I'm new to the Go language.

I'm making a small web application with Go, the Gorilla toolkit, and the Mustache template engine.

Everything works great so far.

I use hoisie/mustache and gorilla/sessions, but I'm struggling with passing variables from one to the other. I have a map[string]interface{} that I pass to the template engine. When a user is logged in, I want to take the user's session data and merge it with my map[string]interface{} so that the data becomes available for rendering.

The problem is that gorilla/sessions returns a map[interface{}]interface{} so the merge cannot be done (with the skills I have in this language).

I thought about extracting the string inside the interface{} variable (reflection?).
I also thought about making my session data a map[interface{}]interface{} just like what gorilla/sessions provides. But I'm new to Go and I don't know if that can be considered best practice. As a Java guy, I feel like working with variables of type Object.

I would like to know the best approach for this problem in your opinion.

Thanks in advance.

答案1

得分: 4

你需要执行类型断言:具体来说,参考Effective Go中的这一部分。

str, ok := value.(string)
if ok {
    fmt.Printf("string value is: %q\n", str)
} else {
    fmt.Printf("value is not a string\n")
}

根据你要做的事情,下面是一个更精确的示例:

if userID, ok := session.Values["userID"].(string); ok {
     // 用户ID已设置
} else {
     // 用户ID未设置/类型错误;抛出错误/HTTP 500/重定向
}

type M map[string]interface{}

err := t.ExecuteTemplate(w, "user_form.tmpl", M{"current_user": userID})
if err != nil {
    // 处理错误
}

你正在确保从interface{}容器中提取的userID实际上是一个字符串。如果不是,你需要处理它(如果不处理,根据文档,程序将会发生panic)。

如果是字符串,你将其传递给模板,可以通过{{ .current_user }}来访问它。M是我用来避免每次调用模板渲染函数时都要输入map[string]interface{}的快捷方式。

英文:

You'll need to perform type assertions: specifically this section of Effective Go.

str, ok := value.(string)
if ok {
    fmt.Printf("string value is: %q\n", str)
} else {
    fmt.Printf("value is not a string\n")
}

A more precise example given what you're trying to do:

if userID, ok := session.Values["userID"].(string); ok {
     // User ID is set
} else {
     // User ID is not set/wrong type; raise an error/HTTP 500/re-direct
}

type M map[string]interface{}

err := t.ExecuteTemplate(w, "user_form.tmpl", M{"current_user": userID})
if err != nil {
    // handle it
}

What you're doing is ensuring that the userID you pull out of the interface{} container is actually a string. If it's not, you handle it (if you don't, you'll program will panic as per the docs).

If it is, you pass it to your template where you can access it as {{ .current_user }}. M is a quick shortcut that I use to avoid having to type out map[string]interface{} every time I call my template rendering function.

huangapple
  • 本文由 发表于 2014年1月30日 12:49:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/21448037.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定