Ruby 的基本概念
运行 ruby 的方式
- irb
- 可交互命令行
- 你每次输入一个式子,他都会用 => 给出一个值
- ruby
- ruby 加文件路径
变量
-
没有关键字
- 没有 var、let、const,直接 a = 1 就行
-
局部变量
- 小写字母开头
- _开头
-
全局变量
- $ 开头
-
类变量
- @@ 开头
-
实例变量
- @ 开头
ruby 默认没有闭包
a = 1
def f1
p a
end
f1() // 括号可以省略
// 报错 :a 不存在
- 闭包是指函数可以使用外部的自由变量
- 没有闭包是指函数 不可以 使用外部的自由变量
- 用 Ruby 其他语法也可以实现闭包
全局变量
$a = 1
def f1
p $a
end
f1()
// 1
- 加上 $ 就是全局变量
常量
A = 1
def f1
p A
end
f1()
// 1
- 大写就是常量
多重赋值(JS叫做析构赋值)
- 简化
- a, b, c = 1, 2, 3
- a, b, *c = 1, 2, 3, 4, 5
- a, *b, c = 1, 2, 3, 4, 5
- 交换
- a, b = b, a
- 数组
- arr = [1, 2]
- a,b = arr
字符串(有十几种)
- 单引号
- 引号里面什么就是什么
- puts '12\n34'
- 不会转义
- 双引号
- puts “12\n34”
- 会把 \n 转义成换行
- 多行字符串
- puts <<xxx(任意字符开头同样结尾,一般用 eos, endOfString)
- 12
- 34
- xxx
- 如果有 \n ,会转义成换行
log
- *打印数据
- print('a', 'b') - 默认不加换行
- puts('a', 'b') - 默认每个加换行
- p 'a', 'b' - 加换行,不转义,且以人类理解的形式加标记
- 只要没有歧义,括号 () 都可以不写
- 使用场景
- 程序员一般使用 p
- 日志一般使用 puts 和 print
注释
- 单行注释
-
这是单行注释
-
这是第二行注释
- 多行注释
- =begin
- 多行注释
- =end
Ruby 的控制语句
ruby 的 if 语句
if a>3 then p '大' end
if a>3 then p '大' else p '小' end
// if 是有返回值的,所以可以直接打印
p(if a>3 then p '大' else p '小' end)
p(if a>4
'大'
elseof a>2
'中'
else
'小'
end)
b = if a>3 then 'big' else 'small' end
b = a>3 ? 'big' : 'small'
return if error // 因为 if 有返回值,所以可以这么简写,如果有 error 就 return 出去
return unless success // 另一种写法 // if not success
case 语句
z = case x
when 1
'1'
when 1,2
'2 or 3'
else
'hi'
end
Ruby 的循环
循环
.times
7.times do
p '一次'
end
7.times { p '一次' } // 用花括号代替 do end
// 等价于 [1,2,3,4,5,6,7].map(v => console.log(v))
获取 i,和插值
|i|
7.times do |i|
p "#{i + 1}次" // 注意要用双引号,不能用单引号
end
7.times { |i|
p "#{i + 1}次"
}
.each (一般用于遍历数组)
name = ['a', 'b']
names.each do |name|
p name
end
(1..7).each do |i| // 两个点构造类似数组的东西,其实他是一个 range((1..7).class)
p i
end
for
// 1 到 5
for i in 1..5 do
p i
end
// 遍历数组
names = ['a', 'b']
for name in names
p name
end
while / until
i = 1
while i<3
p i
i+=1
end
// 和下面等价,与 if,unless 一对对应
j =1
until j>=3
p j
j+=1
end
loop
loop do
p 'ruby'
end
// 上面代码会一直无线循环,除非在里面写 break
跳出循环
- break 表示退出所有循环
- next 表示退出当前循环,进入下一次循环
- 对应 JS 里的 break 和 continue
Ruby 中的数据类型
- 只有对象,可用 .class 查看类
- 不像 JS 有基本类型,ruby 中的数字 1 也是对象(所以 7.time 可以运行)
- 整数 - Intrger 对象 / Numeric 对象
- 浮点数 - Float 对象
- 字符串对象 - String 对象
- 数组 - Array 对象
- 正则表达式 - Regexp 对象
- 时间 - Time 对象
- 文件 - File 对象
- 符号 - Symbol 对象
- 异常 - Exception 对象
- 散列 - Hash 对象
- 标识:每一个对象都有一个 object_id 属性,表示其唯一性([1,2] == [1,2] // true)
Ruby 的数组和散列
Ruby 数组
- arr = [1, 2, 3]
- arr.size // 5
- arr.methods // 打印出所有的方法,如 pop / shift / push / append / find / find_all / each / each_with_index ... 注意这些方法前面都有一个冒号,这是 symbol
Ruby 散列
- 创建一个散列*
- person = {name: 'zch', age: 18}
- symbol
- 上面的 name 和 age 不是字符串,而是 symbol
- person.keys // [:name, :age]
- 打印 person 发现为 person = {:name => 'zch', :age => 18},所以也可以这样声明上面的person(古老的时候都是这么声明的)
-
注意不要使用
person.sex = '男'
来添加属性,因为在 ruby 中所有的.
后面都是方法,上面会被理解成调用 person 的 sex 方法! -
注意可以把 symbol 理解为轻量的字符串,功能更少(打印出
'name'.methods
和:name.methods
即可发现),他把其他字符串其他作为 key 没用的方法都删了,所以作为key一般都使用 symbol - 可以互相转换 :name.to_s 得到字符串,'name'.to_sym 的到符号
遍历散列
.each
- 和数组方法一致,但是多了一个参数
person.each do |key, value|
p "key: #{key},value:#{value}"
end
// 输出时,symbol 会自动变为 string
与 JS 的区别1
- person = {name: 'zch', age: 18}
- 如果你想获取 'zch'
- 不能用 person.name
- 必须用 person[:name]
- 不能用 person['name']
- 必须用 person[:name]
- 'name' 和 :name 是不同的
- person['name'] = 'jack'
- person.keys => [:name, :age, 'name']
与 JS 的区别2
def say_hi
p 'hi'
end
person = {name: 'zch', age: 18}
- 如果想要给 person 加一个方法 / 函数
- 不能用 person[:say_hi] = say_hi
- 因为 say_hi 等价于 say_hi()
- say_hi 的返回值为 p 'hi' 的返回值,也就是 'hi'
- 所以相当于 person[:say_hi] = 'hi'
- 可以使用 lambda 表达式做到
- person[:say_hi] = lambda {p 'hi'}
- person[:say_hi].call // 'hi'
练习:
https://github.com/zch233/ruby-demo1
参考:
https://www.runoob.com/ruby/ruby-tutorial.html
https://devdocs.io/ruby~2.6/
https://apidock.com/ruby/search?query=array&commit=Search