英文:
How to update default values from http.Request elegantly?
问题
我正在做《Go程序设计语言》中的练习1.12,基本上,代码需要根据URL参数更新http.Request中的几个默认值。
这是我正在处理的代码:
var ( // 如果URL中存在相应的参数,则需要更新这些值
cycles = 5
res = 0.001
size = 100
)
我可以逐个进行更新:
if c := r.FormValue("cycles"); c != "" { // r是一个*http.Request
if i, err := strconv.ParseInt(c); err == nil {
cycles = i
}
}
if r := r.FormValue("res"); r != "" {
if f, err := strconv.ParseFloat(r); err == nil {
res = f
}
}
// ...
但是我对这个解决方案不满意:
- 如果我有几十个参数,这样做非常麻烦
- 如何处理转换错误?
重复的模式似乎需要一个函数,像这样(我还不知道如何实现,只是展示我的想法):
func setParam(p interface{}, name string, r *http.Request) error {
if f := r.FormValue(name); f != "" {
switch p.(type) {
case int:
// strconv.ParseInt
case float64:
// strconv.ParseFloat
// ...
}
}
这看起来更好一些,但仍然很麻烦。我不知道这是否是最佳解决方案,或者我是否忽略了Go中应该在这种情况下使用的某些功能。
那么,在这种情况下,什么是惯用的方法呢?
英文:
I'm doing book gopl's exercise 1.12, Basically, the code need to update several default values from http.Request if it is present in URL parameters.
Say here is the code I'm working on:
var ( // Need to update those values if corresponding parameter present in URL
cycles = 5
res = 0.001
size = 100
)
I can do the updating one by one:
if c := r.FormValue("cycles"); c != "" { // r is a *http.Request
i, err := strconv.ParseInt(c); err != nil {
cycles = i
}
}
if r := r.FormValue("res"); r != "" {
if f, err := strconv.ParseFloat(r); err != nil {
res = f
}
}
// ...
But I'm not satisfied by this solution:
- If I have dozens of params, this is very cumbersome
- How to handle the conversion errors?
The repeating pattern seems requires a function, like this (I don't know how to implement it yet, just showing my thought)
func setParam(p interface{}, name string, r *http.Request) error {
if f := r.FormValue(name); f != "" {
switch p.(type) {
case int:
// strconv.ParseInt
case float64:
// strconv.PraseFloat
// ...
}
}
This looks better, but still cumbersome. I don't know if this is the best solution. Or I overlooked some feature in Go that should be used in this situation.
So, what's the idiomatic way to do this?
答案1
得分: 1
编写函数以特定类型获取表单值,如果值缺失则返回默认值。示例:
func intValue(r *http.Request, name string, def int) (int, error) {
if _, ok := r.Form[name]; !ok {
return def, nil
}
return strconv.Atoi(r.FormValue(name))
}
从处理程序中调用这些函数。这段代码与问题中的代码类似,但将变量声明、默认值和获取值合并到一行代码中。
cycles, err := intValue(r, "cycles", 5)
if err != nil {
// TODO: 处理错误值
}
英文:
Write functions that get a form value as a specific type or return default when value is missing. Example:
func intValue(r *http.Request, name string, def int) (int, error) {
if _, ok := r.Form[name]; !ok {
return def, nil
}
return strconv.Atoi(r.FormValue(name))
}
Call these functions from your handler. This is repetitive like the code in the question, but combines variable declaration, default value and fetching value in a single line of code.
cycles, err := intValue(r, "cycles", 5)
if err != nil {
// TODO; handle bad value
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论