在 Ruby初体验一文中,我们探讨了Ruby调试工程的搭建。以此为契机,我们来了解下Ruby的基本语法
Ruby注释和打印
1,使用 #来写注释
使用 put或者print进行输出,put在打印之后,会自动换行,print不会进行换行
puts '1234'
print '12345'
print '123456'
输出结果:
1234
12345123456
2,引用变量:
one = "12333"
puts "AA #{one}"
puts 'AA #{one}'
输出结果:
AA 12333
AA #{one}
这里应注意 单引号和双引号的区别,双引号引入的是变量,单引号引入会变成字符串。
3,执行shell脚本命令
puts `ruby --version`
输出:
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]
Ruby对象、符号、变量
Ruby 对象
在Ruby中,万物皆对象,我们可以用 class查看其类信息
puts 3.class
puts '3'.class
puts nil.class
puts true.class
puts false.class
输出结果:
Integer
String
NilClass
TrueClass
FalseClass
%Q和%q
%Q和%q的使用规则
person = "1223"
puts %Q{#{person}}
puts %q{#{person}}
输出结果:
1223
#{person}
%Q是双引号引用规则,%q是单引号引用规则。
转义字符
转义字符在双引号内,会被解析,在单引号内,不会被解析,照原样输出
puts %q(I can \n。)
puts %Q(I can \n。)
输出结果:
I can \n。
I can
。
变量和符号
定义变量
person = "1223"
puts "#{person}"
输出结果:
1223
Ruby访问变量,是通过Symbol来访问的,Ruby变量是一个结构体,在Ruby中存在symbol-table。symbol在 Ruby 中是唯一的
定义符号 :操作符
:person
puts :person.class
输出结果:
Symbol
符号唯一性:只要符号的名称一致,则符号就是相同的,object_id值也一致。
p = :person
puts p == :person
puts p == :'person'
puts p.object_id
puts :person.object_id
puts 'pe'.object_id
puts 'pe'.object_id
puts 'pe'.object_id
输出结果:
true
true
2700188
2700188
70206614177800
70206614177740
70206614177680
新创建的字符串的 object_id是不同,字符串的值相同,但object_id值不同
符号和字符串的转换
符号和字符串之间的转换
p = :person // 定义变量 p
s1 = p.to_s // 将符号转为字符串
puts s1 // 输出字符串
s2 = s1.to_sym // 将字符串转为符号
puts s2 == p // 输出俩个符号是否相等
输出结果:
person
true
Ruby中的操作符
常见操作符
puts 1 + 1 #=> 2
puts 8 - 1 #=> 7
puts 10 * 2 #=> 20
puts 35 / 5 #=> 7
puts 2**5 #=> 32
puts 5 % 3 #=> 2
puts 3 & 5 #=> 1
puts 3 | 5 #=> 7
puts 3 ^ 5 #=> 6
puts 3.+ 3 #=> 6
puts !!nil #=> false
puts !!false #=> false
puts !!0 #=> true
puts !!"" #=> true
在 Ruby中 !0为false,这里是个值得注意的地方
组合比较运算符
组合比较运算符 <=>:
返回1: 左边参数大。返回0: 两个参数相等。返回-1:右边参数大
puts 1 <=> 10 #=> -1
puts 10 <=> 1 #=> 1
puts 1 <=> 1 #=> 0
and 和 or 运算符
and: 左边执行成功,继续执行右边。
or : 左边执行失败,继续执行右边。
(1 < 0) and (puts "mm") # 无任何输出
(1 < 0) or (puts "cc") # 输出 cc
Ruby中的String
遍历字符串
newStr = "SAE"
newStr.each_byte { |byte|
puts byte
}
puts ">>>>>>>>>>>>>>>>>>>"
newStr.each_byte do |byte|
puts byte
end
输出结果:
83
65
69
>>>>>>>>>>>>>>>>>>>
83
65
69
拼接字符串
puts 'hello ' + 'world'
puts 'hello ' + 3.to_s // 将 Interger 3 转为 字符串
输出结果:
hello world
hello 3
拼接一个对象
newStr = "sss"
puts "Hello " << "World" #=> Hello World
puts "Hello " << newStr #=> Hello sss
重复字符串
newStr = "Hello " * 3
puts newStr
输出结果:
Hello Hello Hello
匹配正则
=~: 返回匹配到字符的索引(如果没有匹配,则返回 nil),//:开启正则。
newStr = "Hello"
index = newStr =~ /o/
puts index
格式化字符串
newStr = "sss "
puts format('%05d', 123)
puts format("%-5s: %08x #{newStr}", 'ID', 44)
输出结果:
00123
ID : 0000002c sss
%05d: 字符串最低长度为5位,不足5位,前面补0
%-5s: 字符串最低长度为5位,不足5位,后面添加空格
%08x: 字符串长度最低为8位,前面补0,并转为16进制
?和 !操作符
在 Ruby中
?:表示返回的是一个布尔值。
puts "123".eql?('123')
输出结果:
true
!:表示具有破环性
str = "11111"
puts str.encoding.name
newStr = str.encode!('ISO-8859-1')
puts str.encoding.name
输出结果:
UTF-8
ISO-8859-1
我们可以看到,在使用encode的时候,改变了原有的字符串编码格式。
Ruby的分支判断、循环和集合
集合
array = [1, 2, 3, 4, 5]
# 数组可以包含多种数据类型
[1, 'hello', false]
puts %w[1 2 3]
%w:写一个用空格而不是逗号分隔且不带引号的字符串数组
向数组中添加元素
array = []
array << 6
array.push(2)
puts array
输出结果:
6
2
分支判断
分支判断:
if true
puts 'if statement'
elsif false
puts 'else if, optional'
else
puts 'else, also optional'
end
循环
for counter in 1..3
puts "iteration #{counter}"
end
输出结果:
iteration 1
iteration 2
iteration 3
闭包
(1..3).each do |counter|
puts "iteration #{counter}"
end
输出结果:
iteration 1
iteration 2
iteration 3
(1..3).each { |counter|
puts "itearation #{counter}"
}
index和value同时存在
(1..3).each_with_index do |element, index|
puts "#{element} is number #{index} in the array"
end
while循环
counter = 1
while counter <= 3 do
puts " while #{counter}"
counter += 1
end
输出结果:
while 1
while 2
while 3
map高阶函数
在Ruby中,没有return关键字。
array = [1,3]
doubled = array.map{|element|
element * 2
}
print(doubled)
输出结果:
[2, 6]
&符号:通过&符号控制对每个元素执行某个方法
a = ["FOO", "BAR", "BAZ"]
array2 = a.map {|s| s.downcase}
puts(array2)
array3 = array2.map(&:upcase)
puts(array3)
输出结果:
["foo", "bar", "baz"]
["FOO", "BAR", "BAZ"]
a.map {|s| s.downcase} 等价于 a.map(&:downcase)
Ruby中的方法与闭包
定义函数
def double(x)
x * 2
end
puts double(2) #=> 4
puts double 3 #=> 6
puts double double 2 #=> 8
通过def关键字定义函数,在Ruby中,没有return关键字,传递参数可以使用括号,也可以不用
yield
yield相似于OC中的block
def logic
puts '{'
yield
puts '}'
end
logic {puts 'Hello World!'}
输出结果:
{
Hello World!
}
Proc
block可以被被 & 修饰后,包装成一个Proc对象,
def guests(&block)
puts block.class
puts block.call(4)
end
# { |n| puts "sss -- #{n}"} 的含义: 传入一个参数 n, 然后输出
guests { |n| puts "sss -- #{n}"} #
输出结果:
Proc
sss -- 4
传递一组参数
*号,在定义函数的时候,表示传递一组参数。
def guess(*arr)
arr.each { |guest| puts guest }
end
guess("1", "ss", "ab")
输出结果:
1
ss
ab
根据数组自动创建对象
a, b, c = ["AA", "BB", "CC"]
puts a
puts b
puts c
输出结果:
"AA"
"BB"
"CC"
arr = [1, 2, 3, 4 ,5, 6, 7, 8]
def get(first, second, third, *other)
puts "#{first} ---#{second}---#{third}"
puts other.count.to_s
end
get(*arr)
输出结果:
1 ---2---3
5
*代表多个参数,数组的前三个数,分别解包为first, second, third,剩下的元素,被解析为other参数的值。
Ruby中的类与继承
@@:表示是类变量。@ : 表示是实例变量。
class Person
// 类变量
@@nickName = "God"
# 初始化方法
def initialize(name, age = 0, gentle = 1)
@name = name
@age = age
@gentle = gentle
end
# setter
def name=(name)
@name = name
end
# getter
def name
@name
end
#自动帮我们生成 getter和setter
attr_accessor :age
# 生成 getter方法
attr_reader :gentle
# 生成 setter方法
attr_writer :gentle
# 类方法
def self.say(msg)
puts msg
end
def personMessage
"年龄: #{age}, 名字:#{name}, 性别:#{gentle}, 外号:#{@@nickName}"
end
end
p = Person.new("小王", 8, 1)
puts p.personMessage
puts Person.say("Hello")
输出结果:
年龄: 8, 名字:小王, 性别:1, 外号:God
Hello
全局变量 $ 和变量查看 defined?
$:用来定义全局变量。 defined?:用来查看变量,检查是有某变量。
$str = "dddddd"
@a1 = "asss"
@@b1 = "bsss"
puts defined? $str
puts defined? @a1
puts defined? @@b1
输出结果:
global-variable
instance-variable
class variable
以大写字母开头的变量是常量
ConstStr = "it is a constant variable"
puts defined? ConstStr
输出结果:
constant
继承
class Human
@@foo = 0
@age = 5
def initialize(foo, age = 0)
@@foo = foo
@age = age
end
def self.foo
@@foo
end
def self.foo=(value)
@@foo = value
end
attr_accessor :age
end
class Worker < Human
end
Human.foo = 5
puts Human.foo
puts Worker.foo
h1 = Human.new(5, 10)
w1 = Worker.new(6,7)
puts h1.age
puts w1.age
在Ruby中,继承是可以共享类属性的。