Is there a way to DRY this?

polaris · · 459 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>(newcomer here)</p> <p>I&#39;m writing a web server and I&#39;m wondering if there&#39;s a better way of doing validation than to repeat code.</p> <pre><code>func handler1(w http.ResponseWriter, r *http.Request) { foo, err := GetParam(r, &#34;foo&#34;) if err != nil { http.NotFound(w, r) return } bar, err := GetParam(r, &#34;bar&#34;) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } restOfCode(foo, bar) } func handler2(w http.ResponseWriter, r *http.Request) { bar, err := GetParam(r, &#34;bar&#34;) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } otherCode(bar) } </code></pre> <p>What are my alternatives? Any ideas? In an ideal world it would be great to have</p> <pre><code>func handler1(w http.ResponseWriter, r *http.Request) { foo, bar := tryParam(&#34;foo&#34;, w, r), tryParam(&#34;bar&#34;, w, r) restOfCode(foo, bar) } func handler2(w http.ResponseWriter, r *http.Request) { bar := tryParam(&#34;bar&#34;, w, r) otherCode(bar) } </code></pre> <p>(edit: formatting)</p> <hr/>**评论:**<br/><br/>xtrmity: <pre><p>Make a variadic function that fetches the params, handles any errors and returns the resulting list if there were no errors.</p> <pre><code>const ( NotFound = iota BadReq ) func GetParams(w http.ResponseWriter, r *http.Request, errHandle int, names ...string) []string { var m = make([]string, 0, len(names)) for _, name := range names { if param, err := GetParam(r, name); err != nil { switch errHandle { case NotFound: http.NotFound(w, r) case BadReq: http.Error(w, err.Error(), http.StatusBadRequest) } return nil } else { m = append(m, param) } } return m } </code></pre> <p>Use it like this:</p> <pre><code>func handler1(w http.ResponseWriter, r *http.Request) { if params := GetParams(w, r, NotFound, &#34;foo&#34;, &#34;bar&#34;); params != nil { restOfCode(params...) } } func handler2(w http.ResponseWriter, r *http.Request) { if params := GetParams(w, r, BadReq, &#34;bar&#34;); params != nil { otherCode(params...) } } ``` </code></pre> <p>If you don&#39;t want to make <code>restOfCode</code> and <code>otherCode</code> variadic, then just pass the individual indexes from the <code>params</code> result.</p></pre>duncanfoo: <pre><p>Make a table of the expected parameters and check the table and error out.</p> <pre><code>if !checkParams([]string {&#34;foo&#34;, &#34;bar&#39;}) { http.NotFound(w, r) return } </code></pre></pre>brianolson: <pre><p>Use a middleware approach of making a barHandler that does the &#34;bar&#34; part and then calls the sub handlers for foo or other code.</p></pre>brianolson: <pre><p>extend Go language to accept macros. Call barStuff() macro inside handler1 and handler2</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

459 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传