英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论