Java转Ruby【快速入门】

最近参加实习了,公司的技术栈中需要用到 Ruby 以及 Rails 框架,所以算是开始了踩坑之旅吧..
1|0Ruby 简介
网上的简介要搜都能搜到,具体涉及的包括历史啦之类这里不再赘述,提几个关键词吧:
- 1993 年由日本的松本行弘创建
- 纯粹面相对象编程/ 脚本语言/ 解释型/ 动态类型
对于准备迈入 Ruby 的 Java 程序员来说,有几个地方需要特别的去了解一下。
- 纯粹面相对象
其实经过论证,Java 同 Ruby 一样都是纯粹的面相对象的语言,这也就意味着包含所有的数字等在内都是对象,注意所有的都是。 - 脚本语言
这意味着你写的程序不用编译就能运行,甚至实时生效。 - 解释型
同 Java 一样,Ruby 有自己的虚拟机,运行需要一定的环境,也就是 Ruby 解释器,它会负责把 Ruby 翻译成及其能够执行的代码。 - 动态类型
Ruby 中的数据更像是一种符号,在使用的时候不检查类型,而是在运行时动态的检查。
1|1为什么是 Ruby ?
- 原因很简单:高效/ 灵活/ 优雅/ 简单
如果你再稍微花一些心思搜索一下 Ruby on Rails 这个 Web 开发框架,并且打开一些详细说明了体验之后的文章或者是多年经验开发者的分享,你可能会对它产生一些兴趣,这一Part就留着之后介绍了,这也是为以后学习 RoR 框架做准备的。
总之我们要明确我们目的:知道最基本的语法,理解其中的一些关键概念即可。
1|2Ruby 初体验
Mac OX 中有默认的 Ruby 环境,我们可以来一个最短的 "Hello World" 程序,首先在控制台中输入 irb
命令,然后输入 puts "Hello World!"
命令:
你就能看到紧跟着你的输入会有一个 Hello World!
的输出以及一个 nil
(对应 Java 中的 null
)的返回。
再来一个更加复杂的例子,我们这一次来创建一个数组然后循环输出它:
不知道感觉如何?至少我们可以直观的感受到:
- 不用生命变量,直接
=
就好 - 每条 Ruby 代码都会返回某个值
1|3从 Java 到 Ruby
Java 非常成熟,并且通过 Spring 的加持得到了许多企业的青睐,但是不知道大家有没有感受到一点:它或许有些啰嗦...(我乱说的啊,我也不知道,别问我啊..)从 Java 到 Ruby 据说可以预见性的将代码的规模量大大缩小,因此也能使用更少的时间来输出产品原型。
相似点
Ruby 与 Java 有一些相似的地方...
- 垃圾回收器帮你管理内存。
- 强类型对象。
- 有 public、 private 和 protected 方法。
- 拥有嵌入式文档工具(Ruby 的工具叫 rdoc)。rdoc 生成的文档与 javadoc 非常相似。
不同点
Ruby 与 Java 不同的地方...
- 你不需要编译你的代码。你只需要直接运行它。
- 有几个不同的流行的第三方GUI工具包。Ruby 用户可以尝试 WxRuby、 FXRuby、 Ruby-GNOME2、 Qt 或 Ruby 内置的 Tk。
- 定义像类这样的东西时,可以使用
end
关键字,而不使用花括号包裹代码块。 - 使用
require
代替import
。 - 所有成员变量为私有。在外部,使用方法获取所有你需要的一切。
- 方法调用的括号通常是可选的,经常被省略。
- 一切皆对象,包括像 2 和 3.14159 这样的数字。
- 没有静态类型检查。
- 变量名只是标签。它们没有相应的类型。
- 没有类型声明。按需分配变量名,及时可用(如:
a = [1,2,3]
而不是int[] a = {1,2,3};
)。 - 没有显式转换。只需要调用方法。代码运行之前,单元测试应该告诉你出现异常。
- 使用
foo = Foo.new("hi")
创建新对象,而非Foo foo = new Foo("hi")
。 - 构造器总是命名为“initialize” 而不是类名称。
- 作为接口的替代,你将获得“混入(mixins)”。
- 相比 XML,倾向于使用 YAML。
nil
替代null
。- Ruby 对
==
和equals()
的处理方式与 Java 不一样。测试相等性使用==
(Java 中是equals()
)。测试是否为同一对象使用equals?()
(Java 中是==
)。
以上的相同与不同来自:https://www.ruby-lang.org/zh_cn/documentation/ruby-from-other-languages/to-ruby-from-java/
延伸阅读:https://gquintana.github.io/2017/01/08/From-Java-to-Ruby.html
2|0Ruby 基础
在大致了解了 Ruby 一些基础信息之后,我们开始 Ruby 基础语法的学习,虽然面对一门新的语言,语法啊特性啊之类的了解很有必要,但还是想在了解之前看一看 Ruby 的一些代码规范,好让自己能快速了解 Ruby 的基础上还能养成一个良好的编码习惯。
2|1学习之前必备 - 代码规范
或许有些语句还不能理解,没关系,有一个基础印象就好。
-
一般来讲,Ruby 中的变量名和方法名使用下划线命名法(小写字母 +
_
),类名和模块名使用 Java 类似的驼峰命名法 -
每个缩进级别使用两个 space(又名软 tabs),不要使用硬 tabs
- 不用使用
;
来分割语句和表达式。以此推论 - 一行使用一个表达式
- 避免单行方法。即便还是会受到一些人的欢迎,这里还是会有一些古怪的语法用起来很容易犯错. 无论如何 - 应该一行不超过一个单行方法.
空方法是这个规则的例外。
- 当赋值一个条件表达式的结果给一个变量时,保持分支的缩排在同一层。
- 在方法定义之间使用空行并且一个方法根据逻辑段来隔开。
- 不要使用区块注释。它们不能由空白引导(=begin 必须顶头开始),并且不如普通注释容易辨认。
- 使用括号将def的参数括起来。当方法不接收任何参数的时候忽略括号。
- 从来不要使用
for
, 除非你知道使用它的准确原因。大多数时候迭代器都可以用来替for
。for
是由一组each
实现的 (因此你正间接添加了一级),但是有一个小道道 -for
并不包含一个新的 scope (不像each
)并且在它的块中定义的变量在外面也是可以访问的。(这里有些像 Java 中不用 for-each 语句类似,感兴趣的也可以去搜一搜)
- 利用
if
andcase
是表达式这样的事实它们返回一个结果。
- 布尔表达式使用
&&/||
,and/or
用于控制流程。(经验Rule:如果你必须使用额外的括号(表达逻辑),那么你正在使用错误的的操作符。)
- 永远不要使用
unless
和else
组合。将它们改写成肯定条件。
- 不用使用括号包含
if/unless/while
的条件。
- 倾向使用
module
,而不是只有类方法的class
。类别应该只在创建实例是合理的时候使用。
- 当你希望将模块的实例方法变成
class
方法时,偏爱使用module_function
胜过extend self
。
- 总是为你自己的类提供
to_s
方法, 用来表现这个类(实例)对象包含的对象.
- 考虑使用
Struct.new
, 它可以定义一些琐碎的accessors
,constructor
(构造函数) 和comparison
(比较) 操作。
- 考虑使用
Struct.new
,它替你定义了那些琐碎的存取器(accessors),构造器(constructor)以及比较操作符(comparison operators)。
-
不要去
extend
一个Struct.new
- 它已经是一个新的class
。扩展它会产生一个多余的class
层级 并且可能会产生怪异的错误如果文件被加载多次。 -
鸭子类型(duck-typing)优于继承。
-
当访问一个数组的第一个或者最后一个元素,倾向使用 first 或 last 而不是 [0] 或 [-1]。
-
优先使用
字符串插值
来代替字符串串联
。
-
在对象插值的时候不要使用
Object#to_s
,它将会被自动调用。 -
操作较大的字符串时, 避免使用
String#+
做为替代使用String#<<
。就地级联字符串块总是比String#+
更快,它创建了多个字符串对象。
-
RuboCop
RuboCop 是一个基于本指南的 Ruby 代码风格检查工具。 RuboCop 涵盖了本指南相当大的部分,支持 MRI 1.9 和 MRI 2.0,而且与 Emacs 整合良好。
基于下面链接简化了大部分,因为有一些编码风格能从 Java 自然的切换过来,而且我们也可以使用相应的工具来检查我们的代码,更多可以看这里:https://ruby-china.org/wiki/coding-style
2|2Ruby 语言基础
其实通过上面的语法规范,我们或多或少能感知到一些 Ruby 的语法,有一些细节的地方可以自行去菜鸟教程or其他网站能看到,下面我们就着一些重要的东西快速的学习一遍吧..
数据类型
Ruby 中有以下几种不同的数据类型:
-
数字/ 字符串/ 符号/ 哈希/ 数组/ 布尔
比较在意的是 Ruby 并没有 Java 中的枚举类型,可能是出于安全方面的考虑吧..(我也不知道...) -
符号就像字符串。一个符号之前是冒号(
:
)。例如:
它们不包含空格。 含有多个单词的符号用(_
)写成。 字符串和符号之间的一个区别是,如果文本是一个数据,那么它是一个字符串,但如果它是一个代码,它是一个符号。
符号是唯一的标识符,表示静态值,而字符串表示更改的值。
示例:
- 哈希将其值分配给其键。 它们可以用键关联指定值。键的值由
=>
符号分配。 键/值对之间用逗号分隔,所有对都用大括号括起来。 例如:
示例:
执行上述代码,得到以下结果:
变量
Ruby 有四种类型的变量,变量的命名方式决定了变量的种类:
-
局部变量
以英文小写字母或者_
开头,作用域等同于 Java 局部变量。 -
全局变量
以$
开头,作用域等同于 Java 全局变量。只要全局变量的名称相同,不管变量在程序的哪个部分使用,程序都认为是它们是同一个变量。未初始化的全局变量的值会被初始化为:nil
。建议不要使用全局变量,因为它们使程序变得秘密和复杂。
示例:
执行代码输出结果如下:
- 实例变量
以@
开头,在同一个实例中,程序可以超越方法定义,任意引用、修改实例变量。它属于类的一个实例,可以从方法中的类的任何实例访问。 它们只能访问一个特定的类的实例。它们不需要初始化,未初始化的实例变量的值是:nil
。
示例:
执行代码输出结果如下:
- 类变量
以@@
开头,作用域为该类的所有实例。需要在使用前进行初始化,由类的所有后代共享,未初始化的变量将导致错误。
示例:
执行上面代码输出结果如下:
类和对象
Object
类是所有 Ruby 对象的默认根。 Ruby 对象继承自 BasicObject
(它是Ruby中所有类的父类)类,允许创建替代对象层次结构。
首先与 Java 很不同的是创建对象:
对比 Ruby:
每个 Ruby 类都是 Class
类的一个实例。通常对于类名,使用驼峰命名规则,类的名称始终以大写字母开头。定义类是用 end
关键字完成的。
语法
我们使用上面学习过的语法规范来创建一个 Person
类(写上 to_s
方法):
注意这里的 attr_reader
对应在 Java 中相当于为 first_name
和 last_name
定义了 getter
,在 Ruby 中,从对象外部不能直接访问实例变量或对实例变量赋值,需要通过方法来访问对象的内部,如果像 Java 那样一遍一遍为每一个变量写 getter/setter
就有些冗杂了,Ruby 为我们提供了一些方便的存取器。
定义 | 意义 |
---|---|
attr_reader :name | 只读(定义 name 方法) |
attr_writer :name | 只写(定义 name= 方法) |
attr_accessor :name | 读写(定义以上两个方法) |
另外一点上面有一个非常有趣的规范是使用
Struct.new
来简化代码,我觉得很酷也想把它应用在上述 Person 类的创建中,但是发现失败了(不能在其中定义其他功能性的代码),所以可能结论是:这样的简化只适用于一些实体类保存数据的类吧。
方法
Ruby 方法使用 def
关键字开始,最后还需要使用 end
关键字来表示方法定义结束。
语法:
示例:
运行上面的代码执行结果如下:
方法返回值:
在初探 Ruby 的时候我们就感受到,貌似每一条指令都会返回一个返回值,方法也是这样,在 Ruby 中每个方法都有一个返回值,这个返回的值将是最后一个语句的值。例如:
上面代码中,最后方法的返回值是 1
。
Ruby return 语句
Ruby 中的 return
语句用于从 Ruby 方法中返回一个或多个值
示例:
上面代码结果如下:
可变参数:
假设声明一个方法需要两个参数,每当调用这个方法时,需要传递两个参数。但是,Ruby允许您声明使用可变数量参数的方法。 让我们来看一下这个示例:
执行上面代码,得到如下结果:
类方法:
当方法在类定义之外定义时,默认情况下该方法被标记为 private
。 另一方面,默认情况下,类定义中定义的方法被标记为 public
。模块的默认可见性和 private
标记可以通过模块的 public
或 private
更改。
Ruby 给出一种不用实例化一个类就可以访问一个方法。下面来看看看如何声明和访问类方法 -
访问类方法 -
模板
Ruby 模块是方法和常量的集合。暂时你可简单的理解为一个不能实例化的类,这样做的好处是一来可以提供一个命名空间避免名字冲突,另一个是实现了 mixin
的功能。
不知道您有没有发现,Ruby 没有提供多重继承的功能,但 Ruby 的模板几乎消除了多重继承的需要,提供了一种名为 mixin
的装置。
示例:
块
Ruby 代码在其他编程语言中被称为闭包。它由一组代码组成,它们始终用大括号括起来,或者在 do..end
之间书写。大括号语法总是具有比 do..end
语法更高的优先级。也就是说大括号优先级高,do..end
优先级低。
语法:
yield语句:
上面代码运行结果如下:
块和方法:
本实例是实现块的最简单的方式。您使用 yield 语句调用 test 块。
但是如果方法的最后一个参数前带有 &
,那么您可以向该方法传递一个块,且这个块可被赋给最后一个参数。如果 *
和 &
同时出现在参数列表中,&
应放在后面。
上述代码运行结果如下:
这一部分建议再去看一下慕课网上的教程,看关于第三章的内容即可:Ruby语言快速入门:https://www.imooc.com/learn/765
3|0总结
经过以上简单的学习,我们对 Ruby 有了一个大致的了解,算是简单入了个门(有一些简单的例如循环啊,判断啊,运算符之类的简单我就没有写了),更多的东西需要自己平时的编码中去总结学习(肯定有一些坑需要自己去填的)。
参考文章:
1.Ruby 教程 - 菜鸟驿站 - http://www.runoob.com/ruby/ruby-intro.html
2.Ruby 教程 - 易百教程 - https://www.yiibai.com/ruby
3.20分钟体验 Ruby - https://www.ruby-lang.org/zh_cn/documentation/quickstart/
4.笨方法学 Ruby - https://lrthw.github.io/intro/
5.Ruby 快速入门 - https://wdxtub.com/2016/03/30/ruby-first-step/
按照惯例黏一个尾巴:
欢迎转载,转载请注明出处!
简书ID:@我没有三颗心脏
github:wmyskxz
欢迎关注公众微信号:wmyskxz
分享自己的学习 & 学习资料 & 生活
想要交流的朋友也可以加qq群:3382693
__EOF__

本文链接:https://www.cnblogs.com/wmyskxz/p/10772690.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?