Ruby基本语法

2,204 阅读6分钟

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!0false,这里是个值得注意的地方

组合比较运算符

组合比较运算符 <=>:

返回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}"
}

indexvalue同时存在

(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中,继承是可以共享类属性的。