在Go语言中是否有可能编写一个“流畅”风格的API?

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

Is it possible to write a 'fluent' style api in go?

问题

几种其他语言具有“流畅”或链式调用风格的API,允许您进行如下调用:

  1. public class CatMap : ClassMap<Cat>
  2. {
  3. public CatMap()
  4. {
  5. Id(x => x.Id);
  6. Map(x => x.Name)
  7. .Length(16)
  8. .Not.Nullable();
  9. Map(x => x.Sex);
  10. References(x => x.Mate);
  11. HasMany(x => x.Kittens);
  12. }
  13. }

值得注意的例子包括流畅的nhibernate,jquery方法链接等。这是一种常见(我会说非常受欢迎)的API设计模式。

问题:Go语法似乎不支持这种方式。

在Go中,您可以这样做:

  1. var blah = X().Y().Thing().OtherThing()

...但是这样:

  1. package main
  2. import "n"
  3. func main() {
  4. n.Log(":D")
  5. .Example()
  6. .Example
  7. }

会导致:

  1. > command-line-arguments
  2. > ./app.go:7: syntax error: unexpected .

...基本上是因为Go会自动在行末插入分号。

有人知道是否有办法解决这个问题吗?

您是否可以在某种程度上禁用自动插入分号?

或者说在Go中这种类型的API是否不可能实现?

英文:

Several other languages have a 'fluent' or chained-invokation style of api, which allows you to do calls like this:

  1. public class CatMap : ClassMap&lt;Cat&gt;
  2. {
  3. public CatMap()
  4. {
  5. Id(x =&gt; x.Id);
  6. Map(x =&gt; x.Name)
  7. .Length(16)
  8. .Not.Nullable();
  9. Map(x =&gt; x.Sex);
  10. References(x =&gt; x.Mate);
  11. HasMany(x =&gt; x.Kittens);
  12. }
  13. }

Notable examples include fluent nhibernate, jquery method chaining, etc. It's a common (and I'd say quite well loved) api design pattern.

Problem: The go syntax doesn't seem to support this.

You can do this in go:

  1. var blah = X().Y().Thing().OtherThing()

...but this:

  1. package main
  2. import &quot;n&quot;
  3. func main() {
  4. n.Log(&quot;:D&quot;)
  5. .Example()
  6. .Example
  7. }

Results in:

  1. &gt; command-line-arguments
  2. &gt; ./app.go:7: syntax error: unexpected .

...basically, because go automatically inserts ;'s at the end of a line.

Anyone know if there's a way around this?

Can you disable the auto-; in a block somehow?

Or is this sort of api just not possible in go?

答案1

得分: 15

你可以重新格式化你的代码为

  1. func main() {
  2. n.Log(":D").
  3. Example().
  4. Example
  5. }

将句号放在行尾可以避免自动分号插入 - 它只会在标识符、字面量或闭合的括号/大括号之后发生。

英文:

You can reformat your code to

  1. func main() {
  2. n.Log(&quot;:D&quot;).
  3. Example().
  4. Example
  5. }

Putting the period at the end of the line avoids automatic semicolon insertion—it only happens after identifiers, literals or closing parens/braces.

答案2

得分: -3

请查看goproxy。我认为其中的一部分是流畅的。

  1. proxy.OnRequest(goproxy.DstHostIs("www.reddit.com")).DoFunc(
  2. func(r *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) {
  3. if h,_,_ := time.Now().Clock(); h >= 8 && h <= 17 {
  4. return r,goproxy.NewResponse(r,
  5. goproxy.ContentTypeText,http.StatusForbidden,
  6. "别浪费时间!")
  7. }
  8. return r,nil
  9. })
英文:

Have a look at goproxy. I think some part of it are fluent.

  1. proxy.OnRequest(goproxy.DstHostIs(&quot;www.reddit.com&quot;)).DoFunc(
  2. func(r *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) {
  3. if h,_,_ := time.Now().Clock(); h &gt;= 8 &amp;&amp; h &lt;= 17 {
  4. return r,goproxy.NewResponse(r,
  5. goproxy.ContentTypeText,http.StatusForbidden,
  6. &quot;Don&#39;t waste your time!&quot;)
  7. }
  8. return r,nil
  9. })

huangapple
  • 本文由 发表于 2013年4月19日 16:21:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/16100317.html
匿名

发表评论

匿名网友

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

确定