有一部分写 ruby/rails 的同鞋是从 java 等语言转过来的,我昨天在网上看到一篇 go 创始人谈论使用 go 语言的很多同鞋是从 ruby/python 等脚本语言转过去的(http://samsungapps.csdn.net/text.html?arcid=2807113),我就有点不太明白了,为什么会这样呢,是因为 ruby/rails 速度不够快又去选择 go 的吗,还是说是因为是根据项目选择合适的语言这样做罢了,或者是自己的兴趣想体验新的语言? 下面这样一条路线也是很多同学的经历吗?
java(others) ->ruby(python...)->go
有相关经验的同鞋可以解答一下哈。
我的个人经验就是,用 Java 的时候,各种架构太复杂,IoC,EJB 各种,之前做 Java 时候从来没自己成功上线过一个项目,因为部署也不简单。当 Rails 出现的时候,感觉看到了曙光,15 分钟就上线 Blog,太快了。写起来太舒服了。
但是后来,项目越写越大,动态脚本语言的缺陷就暴漏出来了,依赖编译都能排除的 Bug,只能通过多写测试来确保了,测试越写越多,越运行越慢,小团队可以,但是有谁见过比如 50 人做一个 Rails 项目,当然能做,但是肯定会花费更多额外的精力。
那 Go 就是编译,并发模型支持,写起来也不像 Java 那么繁琐,但相对 Ruby 还是要繁琐点,性能比 Ruby 强,就是写的时候,只管写代码,实现了,性能基本过得去,但 Ruby 和 Rails 都不一样了。
另外虽然我觉得 Ruby 的 gems 挺好,但是我个人觉得 Go 的包管理更好,稳定的包直接就用,不稳定的 Fork 到自己的 Github 上,进行 hack,然后直接引用自己的包,当然 Ruby 也能这种方式,但是发布 Gem,还是比较有一定的台阶的,不是 Fork 下来就能用这种。
安装依赖,也不用去维护个 gemfile,因为依赖都在代码里,编译器保证了你的依赖在你的代码里调用过的,引用了没调用过的包,你编译都通不过。
记得曾经写过邮件来说服领导,就不翻译了
For my self, I like Go much that I won't like to write program in any another language any more, haha.
A few points of mine:
Go is compiled, the static check is really helpful for trivial bugs, For for large team development, I can't imagine you can work on a ruby project that with 50 more developers. and I imagine our company will be doing big projects eventually.
Go embed synchronized function calls (aka goroutines and channels) are really really good features that otherwise you will require a background job queue to do simliar kind of thing but difficult be synchronized back when you need them
Go is fast enough, I am not saying Ruby is slow, of course you can write fast Ruby programs, But the matter is how hard it is to write fast programs. For a normal developer, that you don't need special training for performance tips, you just write your code in Go, and it's fast enough, The bottle neck is rarely in Go.
Go is simple, Not so much concept about like Mixed in, Meta Programming, Sub Class inherence, Method Overriding, etc, It's just packages, funcs, funcs on struct, structs, package variables. For a new developer, I think it's much easier to learn than any other language.
Go has the best standard package documentations than any other language I know and The most simple and useful standard packages, it's not bloated, but really really useful and can do a lots of things. you just give it a check at http://golang.org/pkg, Until now I still not sure what's the difference between Ruby Core and Ruby Standard Library
Go is so easy to deploy, clone the code on server, run go install and ruby the generated binary command. If you compiled alright on the server, It basically no further problems, and If you compiled wrong, It won't effect the old running binary command.
A lots of concurrency stuff could be easily implemented in Go, please give it a check at: http://concur.rspace.googlecode.com/hg/talk/concur.html#landing-slide
A few people I think is really smart are behind Go:
People outside of Google interesting in Go:
Companies using Go: http://go-lang.cat-v.org/organizations-using-go
Yes, We are new to Go, and Go is new, fewer packages, fewer developers. But I believe it will blossom as time goes. And as our company accumulate more and more Go power, We can do any big project with high quality and good performance, and no mid-night calls for server down, :)
It's just my few points, :-)
另外虽然我觉得 Ruby 的 gems 挺好,但是我个人觉得 Go 的包管理更好,稳定的包直接就用,不稳定的 Fork 到自己的 Github 上,进行 hack,然后直接引用自己的包,当然 Ruby 也能这种方式,但是发布 Gem,还是比较有一定的台阶的,不是 Fork 下来就能用这种。
没看出来 go 的包管理和 Ruby 的有什么区别,按你的说法都是要自己鉴别包是否稳定。 ruby 的 gem 发布有什么门槛儿呢?注册一个 rubygems 帐号,一条 push 命令就 OK。 直接 fork 也一样,只要有自己的 git 源地址就行呀。
安装依赖,也不用去维护个 gemfile,因为依赖都在代码里,编译器保证了你的依赖在你的代码里调用过的,引用了没调用过的包,你编译都通不过。
依赖在代码里本质还是 Vendoring Everything 模式。依赖不冲突么?不需要升级么?
对啊,Fork 实质上就是 Vendor Everything 啊,如果没发现问题,或者新的需求,为什么要升级?升级肯定是包不能满足你的需求了,但是你升级,就是把 Upstream 的代码 Merge 到自己的 Fork 里就行了。然后编译,测试。
依赖不会有冲突啊,两个不同 import 地址的包,就是 2 个包,即使代码一模一样。
如果你一个包的旧版本,在一个项目里面用,新版在另外一个项目里面用,那么就搞出来 2 个仓库,2 个 import 路径,把一个包变成 2 个包。
可以一直存在 2 份啊,这种情况挺常见的,比如你用到的包就是不更新,依赖 A 包的旧版本,但是提供了你需要的必要功能,而你系统就是要 A 包新版本的功能,这样就让他共存着吧。说到底,A 包的旧版和新版实质是 2 个包。
Ruby 里面,包名到处写在代码里面。想改成另外一个包的话,要所有代码替换。但是 Go 里面,代码都不要改,就直接发布到另外一个地址上就可以了,比如 labix.org/v2/mgo 和 labix.org/v1/mgo 实际上就是 2 个包,两份代码,大部分相同,小部分改动过。但是你就是可以一个项目即用 v1 的又用 v2 的。这种自由挺好的。如果我需要增强他的功能,我就 Fork 到 github.com/sunfmin/mgo 这样一个项目里面用 3 个包都没问题。
我觉得 Go 比 Ruby 强太多太多,特别认可的一个说法是 Go 语言是云计算时代的系统语言,相当于现在的 C/C++
但是如果把 Go 和 Rails 放在一起,语言和框架比较的话,我就找不到共通点了,目前我做做的项目,事情,用 Rails 之外,我找不到 Go 的切入点。
或者这么说吧,你在用 Go 导入包的时候
package main
import (
"labix.org/v2/mgo"
v1mgo "labix.org/v1/mgo"
)
func main() {
var rv2 mgo.SomeResult
var rv1 v1mgo.SomeResult
rv2 = rv1 # 这样是付不了值的。
}
就是说,在你的程序里通过 B 的方法返回的 []byte,你就应该知道他是旧驱动的格式,如果你 A 直接调用新驱动的方法返回 []byte,你自然会用新的格式去解析这个 []byte.
把你的问题的“旧驱动”可以替换成“mongo 驱动”,“新驱动”可以替换成“redis 驱动”,本就是 2 个东西,你就不会搞错了吧。
#26 楼 @luikore Go 里面不会用这种通用类型啊,这样写程序太多转换,不爽了,直接声明 Struct,然后把值,直接就搞到 Struct 里面了,如:
import (
"labix.org/v2/mgo"
v1mgo "labix.org/v1/mgo"
)
type Person struct {
Name string
Age int
}
func main(){
session, err := mgo.Dial(url)
var result Person
c := session.DB(database).C(collection)
err := c.Find(query).One(&result)
sessionv1, err := v1mgo.Dial(url)
var resultv1 Person
c := sessionv1.DB(database).C(collection)
err := c.Find(query).One(&resultv1)
}
上面的例子,如果 v1 找出来的数据的 Name 不存在,你自然知道是 v1 的问题啊。
感谢大家的回答,特别是@sunfmin 结合自己的实际工作经验表达了自己对 ruby 和 go 语言的看法。我虽还不清楚 ruby 和 go 很多内部的东东,但是 ruby 和 go 都是值得我去学习的,谢谢。