新手问题 为什么有同鞋学习 Ruby 之后学习 Go??

igordonshaw · 2012年12月13日 · 最后由 vlyonline 回复于 2018年10月31日 · 16327 次阅读

有一部分写 ruby/rails 的同鞋是从 java 等语言转过来的,我昨天在网上看到一篇 go 创始人谈论使用 go 语言的很多同鞋是从 ruby/python 等脚本语言转过去的(http://samsungapps.csdn.net/text.html?arcid=2807113),我就有点不太明白了,为什么会这样呢,是因为 ruby/rails 速度不够快又去选择 go 的吗,还是说是因为是根据项目选择合适的语言这样做罢了,或者是自己的兴趣想体验新的语言? 下面这样一条路线也是很多同学的经历吗?

java(others) ->ruby(python...)->go

有相关经验的同鞋可以解答一下哈。

#1 楼 thanks @huacnlee , 我记得以前好像也有看过 @sunfmin 写的 ruby 教程

记得曾经写过邮件来说服领导,就不翻译了

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:

    • Ken Thomason, Rob Pike, etc those all big guys in IT world no need to explain, :-)
    • Brad Fitzpatrick: The memcached author, Now mainly develop the Go language in Google, and He said he is using Go exclusively now: https://gist.github.com/2396390
    • Russ Cox: Not sure what big thing he do, But I think He is smart.
  • 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, :-)

因为看协程,可以两个参照两者的实现。

#4 楼 @sunfmin 蛮有说服力 :)

#3 楼 @sunfmin

另外虽然我觉得 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 个包。

#8 楼 @hooopo 哦,对了,rubygems 的一点不好就是,不同的 gem 的 Namespace 可能是一个,会相互覆盖,如果项目中有的 gem 依赖另外一个 gem 的旧版,有的 gem 依赖新版,这样就出乱子了。但是在 Go 里面,2 个包就只能存在在 2 个 Namespace 里面,即使里面代码大部分相同,小部分更改。使用不会受到影响。

是啊,ruby 的 gem 包有时候很乱

#7 楼 @sunfmin 在学,没用过。

#11 楼 @sunfmin rubygems 的约定是 namespace 就是 gem 名。gem 名是不可以重复的。 变更用版本号区分。一个项目里不能使用两个相同 gem 的不同版本。 gemfile/gemspec通过对API的兼容性来声明依赖。

go 的这种方式短期内是很好用,起到 hotfix 的作用。但是相同功能的包就这样一直存在两份?多份呢?

可以一直存在 2 份啊,这种情况挺常见的,比如你用到的包就是不更新,依赖 A 包的旧版本,但是提供了你需要的必要功能,而你系统就是要 A 包新版本的功能,这样就让他共存着吧。说到底,A 包的旧版和新版实质是 2 个包。

Ruby 里面,包名到处写在代码里面。想改成另外一个包的话,要所有代码替换。但是 Go 里面,代码都不要改,就直接发布到另外一个地址上就可以了,比如 labix.org/v2/mgo 和 labix.org/v1/mgo 实际上就是 2 个包,两份代码,大部分相同,小部分改动过。但是你就是可以一个项目即用 v1 的又用 v2 的。这种自由挺好的。如果我需要增强他的功能,我就 Fork 到 github.com/sunfmin/mgo 这样一个项目里面用 3 个包都没问题。

因为学 ruby 的人多起来了。

难道就没有人觉得两份相同的包存在在一个项目里是 bad small?使用的时候还要注意两个包的 API 之间的区别,去哪里找文档呢

同意对于人多团队的看法,但是和 @hooopo 一样,不太认同对于包的看法,有点凑数的意思

我觉得 Go 比 Ruby 强太多太多,特别认可的一个说法是 Go 语言是云计算时代的系统语言,相当于现在的 C/C++

但是如果把 Go 和 Rails 放在一起,语言和框架比较的话,我就找不到共通点了,目前我做做的项目,事情,用 Rails 之外,我找不到 Go 的切入点。

#15 楼 @sunfmin java 里引了多个版本的 jar 包的话,相同包名路径下的类有时会莫名挂掉... go 里多版本之间是隔离的?

这种隐蔽问题能避免么:如果 A 依赖 B 和数据库的新驱动,B 依赖数据库的旧驱动,而两个驱动查询结果格式改了,B 有个方法返回旧驱动的查询结果,然后 A 把它当成新驱动的查询结果用...

#20 楼 @luikore 这种情况编译错误,虽然驱动的结果 Struct 名字一样,但是它在不同的包内,是不同的类型,所以付值不会成功的。如果用 Ruby 写的话,你就把 Go 的包理解成这样好了:

V1 版本:

module Sinatra
  module V1
    class Something

    end
  end
end

V2 版本:

module Sinatra
  module V2
    class Something

    end
  end
end

用户用的时候,可以用 Sinatra::V1 也可以用 Sinatra::V2,也可以一起用,本来就是 2 个东西,所以不会冲突或者挂掉。

或者这么说吧,你在用 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 # 这样是付不了值的。
}

#21 楼 @sunfmin 假如两个都返回 byte[] 类型,但是里面内容不一样呢?

#23 楼 @luikore 但是你用的包就明确了他自己使用哪个版本的啊,你搞清楚你用的那个包使用了哪个版本,就知道他的 byte[] 是按照哪个版本去解析了。

就是说,在你的程序里通过 B 的方法返回的 []byte,你就应该知道他是旧驱动的格式,如果你 A 直接调用新驱动的方法返回 []byte,你自然会用新的格式去解析这个 []byte.

把你的问题的“旧驱动”可以替换成“mongo 驱动”,“新驱动”可以替换成“redis 驱动”,本就是 2 个东西,你就不会搞错了吧。

#24 楼 @sunfmin 这就是一个项目里同时用多个版本会出现的问题啊,尤其是 mongodb 这种类型的库,很多方法接收/返回参数类型都是 bson.M, 也就是 *map[string]interface{}, 但是数据内容的处理却不一样 (某版本加了个新参数之类的)...

同意 @hooopo#14 楼 的说法,只不过写 gem 的人得完全的按照 版本定义规则 来写,否则就会出现混乱的情况

#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 都是值得我去学习的,谢谢。

有时间学一下,开阔下思路。

golang 做 web 和 rails 一比,还在石器时代。

#31 楼 @huobazi golang 也有自己的 web 框架 webgo,go 语言具有类似动态语言的语法,写过 ruby/pyton 的同学应该可以很快上手,而且速度又几乎可以与 c 并肩,如果成熟了,可以说是兼具开发速度与程序效率

都是好东西

@sunfmin 弱弱的问问,你们使用 go 的项目是定位在什么领域啊

你关的着么?

对 GO 关注中,感谢精彩点评

如果 go 支持 meta program , 我就学 go

#37 楼 @sevk 那估计你不会学 go 了

好吧,访问不了 go 语言的官网。

#39 楼 @ruby_sky 这是不是说明 go 挺优秀的?

#40 楼 @fsword 之前一直在想,明年学什么新语言,看了上面那么多人的介绍,我懂了。

#42 楼 @sunfmin 哈哈 Thanks. 在轮回前你已经回答啦~

#43 楼 @wppurking 才了解 这里又回到从前了。。。

#23 楼 @luikore #44 楼 @sunfmin

你从一个程序员角度讲都有道理,你从一个老板的角度讲 JAVA, .NET 对于企业级,政府大项目都是刚需。 你找 Rails, go 独当一面的程序员少之又少。对于程序员来说,语言不决定一切,工资待遇市场决定是否入行。 我也觉得 go 很好,我也用,好使,快。

因为用 ruby 的公司基本上都面试完了,没有工作机会了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号