Ruby 入门基本语法
简介
Ruby,一种为简单快捷面向对象编程(面向对象程序设计)而创的脚本语言,由日本人松本行弘(まつもとゆきひろ,英译:Yukihiro Matsumoto,外号Matz)开发,遵守GPL协议和Ruby License。
特色
- 完全面向对象,在Ruby语言中,任何东西都是对象,包括其他语言中的基本数据类型,比如整数
- 变量没有类型,Ruby的变量可以保有任何类型的数据
- 任何东西都有值,不管是数学或者逻辑表达式还是一个语句,都有值
- 运算符重载
- 自动垃圾回收
- 弱类型(动态类型 | 标量变量)
- 变量无需声明 (不必事先宣告变量)
一、入门:
hello world!
每个语言我们都从"hello world!" 开始,让我们见识下 ruby
- 标准版:
print "hello world!"
- 加长版:
puts "hello world!"
- 精简版:
p "hello world!"
注释
- 单行注释:
# say hello
- 块注释:
=begin
say hello
=end
变量
Ruby支持五种类型变量:
- 一般小写字母、下划线开头:变量
- $开头:全局变量
- @开头:实例变量
- @@开头:类变量
- 大写字母开头:常数
全局变量:
全局变量以 $ 开头。给全局变量赋值会改变全局状态,所以不建议使用全局变量。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
$global_variable = 10
class Dog
def print_global
p "输出全局变量 #{$global_variable}"
end
end
dog = Dog.new
dog.print_global
实例变量:
实例变量以 @ 开头。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
class Dog
def initialize(id, name, age)
@id = id
@name = name
@age = age
end
def details
p "id #{@id}"
p "name #{@name}"
p "age #{@age}"
end
end
dog = Dog.new("666", "dog", "6")
dog.details
类变量:
类变量以 @@ 开头,且必须初始化后
才能在方法定义中使用。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
class Dog
@@total_nums= 0 # 类变量
def initialize(id, name, age)
@id = id
@name = name
@age = age
end
def total_nums
@@total_nums += 1
p "total nums #{@@total_nums}"
end
end
dog = Dog.new("666", "dog", "18")
dog.total_nums
数据类型
Ruby支持的数据类型包括基本的,数值类型、字符串类型、数组、哈希类型、范围类型
1.数值类型:
整型:
整形分为两种:如果在31位内(四字节),那么为Fixnum实例,如果超出,为Bignum实例
。
666 # Fixnum 十进制
-666 # Fixnum 带有下划线的十进制
0377 # 八进制
0xff # 十六进制
0b1011 # 二进制
"a".ord # "a"的字符编码
12345678901234567890 # Bignum 大数
浮点型:
123.4 # 浮点值
1.0e6 # 科学记数法
4E20 # 不是必需的
4e+20 # 指数前的符号
浮点数注意事项:
- 浮点数转整数,会强行
去掉小数点后面数字
:
irb(main):017:0> 123.45.to_i
=> 123
- 整数转浮点数,会
添加小数点和0
:
irb(main):018:0> 123.to_f
=> 123.0
- 浮点数转换成字符串,会
去掉最后多余的0
:
irb(main):021:0> 123.1230.to_s
=> "123.123"
- 运算:
irb(main):021:0> 1 / 4
=>0
irb(main):021:0> 1 / 4.0
=>0.25
2.字符串类型:
Ruby 字符串简单地说是一个8 位字节序列。
Ruby 字符串分为单引号字符串(’)和双引号字符串("),区别在于双引号字符串能够支持更多的转义字符
。
双引号字符串:
在双引号字符串中我们可以使用 #{} 井号和大括号来计算表达式的值:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
name1 = "lv"
name2 = "huiqi"
puts "你好 #{name1}, #{name2}"
# 输出结果: 你好 lv, huiqi
%q 和 %Q 的使用:
Ruby 中还支持一种采用 %q 和 %Q 来引导的字符串变量,%q 使用的是单引号引用规则,而 %Q 是双引号引用规则。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
data1 = %Q{Ruby 的字符串可以使用 '' 和 ""。}
data2 = %q|Ruby 的字符串可以使用 '' 和 ""。|
3.数组:
数组字面量通过[]中以逗号分隔定义,且支持range定义。
- 数组通过[]索引访问,数组索引从0开始,一个负数相对于数组的末尾计数(索引为-1表示数组的最后一个元素)
- 数组可以存储:String、 Integer、 Fixnum、 Hash、 Symbol 等对象,甚至可以是其他 Array 对象
- 通过赋值操作插入、删除、替换元素
- 通过+,-号进行合并和删除元素
- 通过<<号向原数据追加元素
- 通过*号重复数组元素
- 通过|和&符号做并集和交集操作
- 数组不需要指定大小,当向数组添加元素时,Ruby 数组会自动增长
创建数组:
- 通过new类方法:
array = Array.new
- 创建时,给每个元素赋值:
array = Array.new(4, "abc")
puts array
# 输出结果: ["abc", "abc", "abc", "abc"]
- 也可用new的块,每个元素使用块中的计算结果来填充:
array = Array.new(4){|i| i = i ** 2}
p array
# 输出结果:[0, 1, 4, 9]
- 数组创建另一种形式:
array = Array[1, 2, 3, 4, 5, 6]
p array
# 输出结果:[1, 2, 3, 4, 5, 6]
- 使用范围作为参数来创建一个数字数组:
array = Array(0..9)
p array
# 输出结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4.哈希:
哈希是类似 "key" => "value" 这样的键值对集合
。哈希类似于一个数组,只不过它的索引不局限于使用数字。
创建哈希:
- 通过
new类方法
创建一个空的哈希:
hash = Hash.new
- 使用[]创建哈希:
hash = Hash["a" => 100, "b" => 200, [666,"array"] => "Array"]
p hash # 输出结果:{"a"=>100, "b"=>200, [666, "array"]=>"Array"}
p hash["a"] # 输出结果:100
p hash["c"] # 输出结果: nil 因为key不存在返回nil
p hash[[666, "array"]] # 输出结果:"Array"
注意:Ruby 的哈希 跟Python语言的字典略有不同,Python中的字典key是不变类型,而Ruby的key可以是数组;
5.范围:
Ruby 使用 ‘’…’’ 和 ‘’…’’ 范围运算符创建这些序列。两点形式创建一个包含指定的最高值的范围,三点形式创建一个不包含指定的最高值的范围
。
创建范围:
(1…10)是一个Range对象,可以使用to_a方法把范围转换为列表:
range_a = (1..10).to_a
p range_a # 输出结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
范围的使用:
nums = (1..10)
p nums.include?(5) # 判断是否包含5的数值
# 输出结果:true
p nums.min # 获取最小值
# 输出结果: 1
p nums.max # 获取最大值
# 输出结果:10
p nums.reject {|i| i < 5} # 不符合条件的数值有
# 输出结果:[5, 6, 7, 8, 9, 10]
nums.each do |num|
p "循环 #{num}"
end
# 输出结果如下:
"循环 1"
"循环 2"
"循环 3"
"循环 4"
"循环 5"
"循环 6"
"循环 7"
"循环 8"
"循环 9"
"循环 10"
条件范围:
score = 68
result = case score
when 0..60
"不及格"
when 61..80
"及格"
when 81..90
"良好"
when 91..100
"优秀"
else
"分数不对"
end
p result
# 输出结果:"及格"
间隔的范围:
需要使用 === 相等运算符来完成计算
。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
if ((1..10) === 5)
puts "5 在 (1..10)"
end
if (("a".."f") === "z")
puts "c 在 (a...j)"
end
# 输出结果:
5 在 (1..10)
类型转换
- 字符转数值:to_i
- 数值转字符:to_s
- 数值转换成浮点数:to_f
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
# 将数值转换成字符
abc = 123
puts abc.class
puts abc.to_s.class
# 输出结果如下:
Integer
String
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
# 字符转换成数值
abc = "123"
puts abc.class
puts abc.to_i.class
# 输出结果如下:
String
Integer
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
# 数值转换成浮点数
abc = 123
puts abc.class
puts abc.to_f.class
# 输出结果如下:
Integer
Float
条件判断
1.if…elsif…else:
注意:Ruby 使用elsif,不是使用 else if 和 elif。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
x = 6
if x > 2
p "x 大于2"
elsif x <= 2 and x != 0
p "x 是 1"
else
p "没有进行匹配"
end
# 输出结果:"x 大于2"
2.if 修饰符:
if 修饰词组表示当 if 右边条件成立时才执行 if 左边的式子。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
x = 6
p "x=6" if x == 6
# 输出结果:"x=6"
3.unless 语句:
unless式和if 作用相反。
x = 6
unless x > 2
p "x 小于 2"
else
p "x 大于 2"
end
# 输出结果:"x 大于 2"
4.unless 修饰符:
与 if修饰符相反。
x = 6
p "x=6" unless x == 1
# 输出结果: "x=6"
5.case语句:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
x = 6
case x
when 0..2
p "0~2"
when 3..5
p "3~5"
when 6..8
p "6~8"
when 9..10
p "9~10"
else
p "其他"
end
当case表达式 部分被省略时,将计算第一个when条件部分为真表达式。
a = true
b = false
c = false
case
when a then p "输出a为真"
when b then p "输出b为真"
when c then p "输出c为真"
else p "都为假"
end
# 输出结果:"输出a为真"
三元运算符
Ruby 三元运算符比 if 更强大
puts 1 < 2? "One": "Two"
- 1 < 2 条件满足 输出 冒号前面的数据,若不满足,输出冒号后面的数据
循环
1.while 语句:
语法中do 可以省略不写
。但若要在一行内写出 while 式,则必须以 do 或 : 隔开条件式或程式区块。
$i = 0
$num = 5
while $i < $num
p "循环语句 i = #{$i}"
$i += 1
end
# 输出结果 :
"循环语句 i = 0"
"循环语句 i = 1"
"循环语句 i = 2"
"循环语句 i = 3"
"循环语句 i = 4"
2.until语句:
与 while 语句相反。
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
$i = 0
$num = 5
until $i > $num
p "循环语句 i = #{$i}"
$i += 1
end
3.for语句:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
analyse_items=["QPS", "解析成功率", "缓存命中率"]
for item in analyse_items
puts item
end
#循环1-5
for num in 1..5 do
puts num
end
注意:
- …包含、…不包含结束步长
4.each循环:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
analyse_items=["QPS", "解析成功率", "缓存命中率"]
analyse_items.each do |item|
puts item
end
获取数值与索引(each_with_index):
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
analyse_items=["QPS", "解析成功率", "缓存命中率"]
analyse_items.each_with_index do |item, index|
puts item, index
end
5.times循环:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
5.times do |item|
puts "#{item+1} 次times循环"
end
# 输出结果:
1 次times循环
2 次times循环
3 次times循环
4 次times循环
5 次times循环
6.step循环:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
# 1~10 每隔3个数取出来1个数
1.step(10, 3) do |item|
puts "#{item}"
end
# 输出结果:
1
4
7
10
7.upto循环:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
# 取出2~5的数值
2.upto(5) do |i|
puts i.to_s
end
# 输出结果如下:
2
3
4
5
8.downto循环:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
# 输出5~2的数值
5.downto(2) do |i|
puts i.to_s
end
# 输出结果如下:
5
4
3
2
异常处理
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
begin
# 有可能发送错误的处理
puts "begin_____开始抛出异常"
10 / 0
rescue => e
# 错误发生时走这里
puts "rescue_____错误发生时走这里"
puts e
else
# begin正常时走这里
puts "else______begin 正常时走这里"
ensure
# 无论正常还是错误的时, 都会走这里
puts "ensure_____无论正常还是错误都走这里"
end