Using Go 1.9 type aliases

polaris · 2017-10-04 16:00:07 · 502 次点击    
这是一个分享于 2017-10-04 16:00:07 的资源,其中的信息可能已经有所发展或是发生改变。

In a small project that I am writing, I have a package models that exposes a type Transaction. In another package controllers, I make frequent reference to models.Transaction.

From a a purely software engineering perspective, what would be the advantages and disadvantages of using the new Go 1.9 type alias language feature to alias models.Transaction as Transaction in the controllers package (type Transaction = models.Transaction) so that I don't need to type models. at every reference, setting aside the arguments about how easy it is to type models.Transaction using a modern editor?

I'm not saying that I am going to do this. I just thinking about the implications.


评论:

ChristophBerger:

Maybe it helps if considering the original use case for type aliases: To support gradual code repair, as outlined here.

The goal is to move a type from one package to another without breaking client code that still refers to the type in the old package. Then, after all client packages have been refactored to refer to the new package only, the alias can be removed and the old package can be retired.

So the original intent was to use type aliases only temporarily during phases of refactoring. (Which IMHO does not exclude any other use that seems justifiable.)

For your use case (of using a type alias permanently as a shortcut to a type in another package), I see two main consequences:

  • Easier to write (as you said, this saves some typing)
  • But maybe harder to comprehend when reading the code (as the reader loses the mental reference to the models package.)
skidooer:

If it is simply for reducing keystrokes, why type aliases over 'dot' imports? The latter only requires two extra characters per package.

From a software engineering perspective, based on your description, I find myself asking if Transaction is actually a separate concern that warrants a separate package in the first place? To pick a random example from the standard library, the http.Client type is controller-like and the http.Request type is model-like, but they live in the same package as they are of the same concern.

I would suggest that if you have good reason to think of these as a separate concerns, I think it warrants letting the reader of your code explicitly see it as a separate concern. Aliasing the type makes it a local package concern, in which case, in your case, you may as well ditch the alias entirely and move the entire type into that package. In fact, your example exports the controllers.Transaction type, which may be unintended for consumers of your package.

shovelpost:

models.Transaction

Models is a not a very good package name. Same goes with controllers. They don't tell anything about the package. Use better package names and you won't even think about aliases anymore.

grkuntzmd:

@skidooer and @shovelpost: I agree with separating Transactions into its own package as a separate concern, and when I first started writing Go about 2 years ago, that is what I would have done, but now tend toward fewer, larger packages. In Ben Johnson's blog Structuring Applications in Go, in section 4, he talks about sub-packages. Because Go does not allow cyclic dependencies, it is easy to get into trouble with package A depending on B and B depending on A. I found that I had to combine A and B into some artificial package AB to accommodate the inter-dependency, so I stopped making so many sub-packages.

As far as using the type alias feature to pull a type into another package, I agree that it is not a great choice, and I was really only doing a "thought experiment". I also shy away from "." imports because they pollute the namespace unnecessarily.


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

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