Ruby 基础语法全面解析
变量与数据类型
变量
在 Ruby 中,变量的命名遵循一定规则。变量名以字母或下划线开头,后续字符可以是字母、数字或下划线。变量名区分大小写。
Ruby 有几种不同类型的变量:
- 局部变量:以小写字母或下划线开头。例如:
name = "John"
_age = 30
局部变量的作用域通常是定义它的方法、块或循环内。一旦超出这个范围,变量就无法访问。
- 实例变量:以
@
符号开头。实例变量主要用于类的实例中,不同实例的实例变量相互独立。
class Person
def initialize(name)
@name = name
end
def show_name
puts @name
end
end
person1 = Person.new("Alice")
person1.show_name
在上述代码中,@name
是 Person
类的实例变量,每个 Person
实例都有自己的 @name
副本。
- 类变量:以
@@
符号开头。类变量在类的所有实例之间共享。
class Counter
@@count = 0
def initialize
@@count += 1
end
def self.show_count
puts @@count
end
end
counter1 = Counter.new
counter2 = Counter.new
Counter.show_count
这里 @@count
是 Counter
类的类变量,无论创建多少个 Counter
实例,@@count
都是共享的。
- 全局变量:以
$
符号开头。全局变量在整个程序中都可访问,但过度使用全局变量可能导致代码难以维护,因为任何部分的代码都可以修改它。
$global_variable = "This is a global variable"
puts $global_variable
数据类型
- 整数:Ruby 支持不同进制的整数表示。十进制是默认的,也可以使用十六进制(以
0x
开头)、八进制(以0
开头)和二进制(以0b
开头)。
decimal_num = 10
hex_num = 0x10 # 十六进制,等于十进制的16
octal_num = 010 # 八进制,等于十进制的8
binary_num = 0b10 # 二进制,等于十进制的2
整数可以进行常见的算术运算,如加法、减法、乘法和除法。
a = 5
b = 3
puts a + b # 输出8
puts a - b # 输出2
puts a * b # 输出15
puts a / b # 输出1,因为是整数除法,结果会截断小数部分
puts a % b # 输出2,取模运算
- 浮点数:用于表示带有小数部分的数字。
float_num1 = 3.14
float_num2 = 1.5e2 # 科学计数法,等于150.0
浮点数运算与整数运算类似,但需要注意浮点数精度问题。
a = 0.1
b = 0.2
puts a + b # 理论上应是0.3,但实际输出可能接近0.30000000000000004,这是浮点数精度问题
- 字符串:在 Ruby 中,字符串是不可变对象。可以使用单引号或双引号创建字符串。
single_quoted_string = 'This is a single - quoted string'
double_quoted_string = "This is a double - quoted string"
双引号字符串支持字符串插值,即可以在字符串中嵌入变量。
name = "Ruby"
message = "Hello, #{name}!"
puts message # 输出Hello, Ruby!
字符串有许多实用的方法,如 length
获取字符串长度,upcase
转换为大写,downcase
转换为小写等。
str = "ruby programming"
puts str.length # 输出15
puts str.upcase # 输出RUBY PROGRAMMING
puts str.downcase # 输出ruby programming
- 布尔值:Ruby 中有两个布尔值:
true
和false
。布尔值常用于条件判断。
is_true = true
is_false = false
if is_true
puts "This is true"
else
puts "This is false"
end
- 数组:数组是有序的对象集合,可以包含不同类型的元素。
array1 = [1, "two", true]
array2 = Array.new(3, "default") # 创建一个包含3个"default"的数组
可以通过索引访问数组元素,索引从 0
开始。
array = [10, 20, 30]
puts array[0] # 输出10
puts array[1] # 输出20
数组有很多有用的方法,如 push
向数组末尾添加元素,pop
从数组末尾移除元素,join
将数组元素连接成字符串等。
array = [1, 2, 3]
array.push(4)
puts array # 输出[1, 2, 3, 4]
array.pop
puts array # 输出[1, 2, 3]
str = array.join(', ')
puts str # 输出1, 2, 3
- 哈希:哈希是键值对的集合,其中键是唯一的。
hash1 = {name: "Ruby", version: 2.7}
hash2 = Hash.new("default value") # 创建一个默认值为"default value"的哈希
可以通过键来访问哈希的值。
hash = {city: "New York", country: "USA"}
puts hash[:city] # 输出New York
哈希也有许多方法,如 keys
获取所有键,values
获取所有值,each
遍历哈希的键值对等。
hash = {a: 1, b: 2}
hash.each do |key, value|
puts "#{key}: #{value}"
end
运算符
算术运算符
- 加法(
+
):用于两个数相加。
a = 5
b = 3
sum = a + b
puts sum # 输出8
- 减法(
-
):用于两个数相减。
a = 5
b = 3
difference = a - b
puts difference # 输出2
- 乘法(
*
):用于两个数相乘。
a = 5
b = 3
product = a * b
puts product # 输出15
- 除法(
/
):整数除法会截断小数部分,如果需要得到浮点数结果,至少有一个操作数应为浮点数。
a = 5
b = 3
integer_division = a / b
puts integer_division # 输出1
float_division = a.to_f / b
puts float_division # 输出1.6666666666666667
- 取模(
%
):返回除法的余数。
a = 5
b = 3
modulo = a % b
puts modulo # 输出2
- 幂运算(
**
):计算一个数的指定次幂。
a = 2
b = 3
power = a ** b
puts power # 输出8
比较运算符
- 等于(
==
):比较两个值是否相等。
a = 5
b = 5
puts a == b # 输出true
- 不等于(
!=
):比较两个值是否不相等。
a = 5
b = 3
puts a != b # 输出true
- 大于(
>
):比较左边的值是否大于右边的值。
a = 5
b = 3
puts a > b # 输出true
- 小于(
<
):比较左边的值是否小于右边的值。
a = 3
b = 5
puts a < b # 输出true
- 大于等于(
>=
):比较左边的值是否大于或等于右边的值。
a = 5
b = 5
puts a >= b # 输出true
- 小于等于(
<=
):比较左边的值是否小于或等于右边的值。
a = 5
b = 5
puts a <= b # 输出true
逻辑运算符
- 逻辑与(
&&
):只有当两个操作数都为true
时,结果才为true
。
a = true
b = false
puts a && b # 输出false
- 逻辑或(
||
):只要有一个操作数为true
,结果就为true
。
a = true
b = false
puts a || b # 输出true
- 逻辑非(
!
):对操作数进行取反,true
变为false
,false
变为true
。
a = true
puts!a # 输出false
赋值运算符
- 简单赋值(
=
):将右边的值赋给左边的变量。
a = 5
- 复合赋值运算符:如
+=
、-=
、*=
、/=
、%=
等。
a = 5
a += 3 # 等同于 a = a + 3
puts a # 输出8
其他运算符
- 范围运算符(
..
和...
):..
表示包含两端的范围,...
表示不包含右端点的范围。
range1 = 1..5 # 包含1到5
range2 = 1...5 # 包含1到4
范围可以用于循环等场景。
(1..5).each do |num|
puts num
end
- 三元运算符(
? :
):是一种简洁的条件判断表达式。
a = 5
result = a > 3? "Greater" : "Less"
puts result # 输出Greater
控制结构
if - else 语句
if - else
语句用于根据条件执行不同的代码块。
age = 20
if age >= 18
puts "You are an adult"
else
puts "You are a minor"
end
还可以使用 elsif
处理多个条件。
score = 85
if score >= 90
puts "A"
elsif score >= 80
puts "B"
elsif score >= 70
puts "C"
else
puts "D"
end
case 语句
case
语句用于根据不同的值执行不同的代码块,类似于其他语言中的 switch - case
。
day = "Monday"
case day
when "Monday"
puts "Start of the week"
when "Friday"
puts "Nearing the weekend"
else
puts "Another day"
end
case
语句也可以用于比较范围等。
number = 5
case number
when 1..3
puts "Small number"
when 4..6
puts "Medium number"
else
puts "Large number"
end
循环结构
while
循环:只要条件为true
,就会重复执行代码块。
i = 0
while i < 5
puts i
i += 1
end
until
循环:与while
循环相反,只要条件为false
,就会重复执行代码块。
i = 0
until i >= 5
puts i
i += 1
end
for
循环:用于遍历数组、范围等。
array = [1, 2, 3]
for num in array
puts num
end
each
方法:许多可枚举对象(如数组、哈希)都有each
方法,用于遍历其中的元素。
array = [1, 2, 3]
array.each do |num|
puts num
end
hash = {a: 1, b: 2}
hash.each do |key, value|
puts "#{key}: #{value}"
end
方法定义与调用
方法定义
在 Ruby 中,使用 def
关键字定义方法。
def greet(name)
puts "Hello, #{name}!"
end
上述代码定义了一个名为 greet
的方法,它接受一个参数 name
,并输出问候语。
方法可以有默认参数。
def greet(name = "Guest")
puts "Hello, #{name}!"
end
这样,在调用 greet
方法时,如果不传递参数,会使用默认值 "Guest"
。
方法调用
方法调用非常简单,只需使用方法名并传递必要的参数。
def add(a, b)
a + b
end
result = add(3, 5)
puts result # 输出8
如果方法没有参数,调用时可以省略括号。
def say_hello
puts "Hello"
end
say_hello
类与对象
类的定义
使用 class
关键字定义类。
class Dog
def initialize(name, breed)
@name = name
@breed = breed
end
def bark
puts "#{@name} says Woof!"
end
end
在上述代码中,Dog
类有一个构造方法 initialize
,用于初始化对象的属性 @name
和 @breed
,还有一个 bark
方法用于让狗叫。
对象的创建与使用
通过调用类的构造方法来创建对象。
dog1 = Dog.new("Buddy", "Golden Retriever")
dog1.bark
这里创建了一个 Dog
类的实例 dog1
,并调用了它的 bark
方法。
继承
Ruby 支持类的继承,使用 <
符号表示继承关系。
class Bulldog < Dog
def snore
puts "#{@name} is snoring"
end
end
Bulldog
类继承自 Dog
类,它继承了 Dog
类的所有方法和属性,并且还可以定义自己特有的方法,如 snore
。
bulldog1 = Bulldog.new("Max", "Bulldog")
bulldog1.bark
bulldog1.snore
模块
模块定义
模块使用 module
关键字定义。模块主要用于将相关的方法和常量组织在一起,避免命名冲突。
module MathUtils
PI = 3.14159
def self.add(a, b)
a + b
end
def self.multiply(a, b)
a * b
end
end
上述 MathUtils
模块定义了一个常量 PI
和两个类方法 add
和 multiply
。
模块的使用
可以通过模块名来访问模块中的方法和常量。
puts MathUtils::PI
result = MathUtils.add(3, 5)
puts result
模块还可以通过 include
关键字混入到类中,使类具有模块中的实例方法。
class Shape
include MathUtils
def area(radius)
multiply(PI, radius ** 2)
end
end
circle = Shape.new
puts circle.area(5)
异常处理
异常的抛出与捕获
在 Ruby 中,可以使用 raise
关键字抛出异常。
def divide(a, b)
if b == 0
raise ZeroDivisionError, "Cannot divide by zero"
end
a / b
end
上述 divide
方法在除数为 0
时抛出 ZeroDivisionError
异常。
使用 begin - rescue
块来捕获异常。
begin
result = divide(10, 0)
rescue ZeroDivisionError => e
puts "Error: #{e.message}"
end
这里捕获了 ZeroDivisionError
异常,并输出异常信息。
自定义异常
可以通过继承 StandardError
类来定义自己的异常。
class MyCustomError < StandardError
end
def some_method
raise MyCustomError, "This is a custom error"
end
begin
some_method
rescue MyCustomError => e
puts "Caught custom error: #{e.message}"
end
块与迭代器
块
块是一段未命名的代码,用花括号 {}
或 do...end
包围。
(1..5).each { |num| puts num }
上述代码中,{ |num| puts num }
就是一个块,它会对 (1..5)
中的每个数字执行 puts num
操作。
迭代器
迭代器是一个方法,它会对集合中的每个元素执行给定的块。除了 each
外,还有许多其他迭代器,如 map
、select
等。
map
迭代器:对集合中的每个元素应用给定的块,并返回一个新的集合。
array = [1, 2, 3]
new_array = array.map { |num| num * 2 }
puts new_array # 输出[2, 4, 6]
select
迭代器:选择集合中满足给定块条件的元素,并返回一个新的集合。
array = [1, 2, 3, 4, 5]
even_numbers = array.select { |num| num.even? }
puts even_numbers # 输出[2, 4]
文件操作
文件读取
使用 File.read
方法可以读取整个文件内容。
content = File.read('example.txt')
puts content
也可以逐行读取文件。
File.foreach('example.txt') do |line|
puts line
end
文件写入
使用 File.write
方法可以写入文件,如果文件不存在会创建文件。
File.write('output.txt', "This is some text")
如果要追加内容到文件,可以使用 File.open
并指定 'a'
模式。
File.open('output.txt', 'a') do |file|
file.puts "This is additional text"
end
正则表达式
正则表达式基础
在 Ruby 中,正则表达式使用 /pattern/
形式定义。例如,匹配字符串中的数字:
string = "There are 10 apples"
match = string.match(/\d+/)
puts match.to_s # 输出10
这里 /\d+/
是一个正则表达式,\d
表示匹配任意数字,+
表示匹配前面的字符一次或多次。
正则表达式方法
字符串有许多与正则表达式相关的方法,如 match
、gsub
等。
match
方法:尝试在字符串中匹配正则表达式,返回匹配结果。
string = "Hello, World!"
match = string.match(/Hello/)
puts match.to_s # 输出Hello
gsub
方法:全局替换字符串中匹配正则表达式的部分。
string = "aabbcc"
new_string = string.gsub(/a/, 'x')
puts new_string # 输出xxbbcc
通过以上对 Ruby 基础语法的全面解析,希望能帮助你深入理解和掌握 Ruby 语言,为进一步的编程实践和项目开发打下坚实基础。在实际应用中,还需要不断练习和积累经验,以更好地发挥 Ruby 的强大功能。