1. 什么是范围?
范围(Range
)表示一个连续的区间,由起始值和结束值定义。Ruby 中用 ..
或 ...
创建范围:
..
:包含结束值(闭区间)。...
:不包含结束值(半开区间)。
基本定义
range1 = 1..5 # 包含 1 到 5
range2 = 1...5 # 包含 1 到 4,不含 5
puts range1.to_a # [1, 2, 3, 4, 5]
puts range2.to_a # [1, 2, 3, 4]
2. 创建范围
数字范围
numbers = 0..3
puts numbers.to_a # [0, 1, 2, 3]
字符范围
letters = "a".."c"
puts letters.to_a # ["a", "b", "c"]
# 中文字符
chars = "你".."他"
puts chars.to_a # ["你", "他"](按 Unicode 顺序)
注意
- 字符范围按 Unicode 编码排序,中文支持有限(通常只包含起止点)。
3. 常用方法
转换为数组
range = 1..4
puts range.to_a # [1, 2, 3, 4]
检查包含
include?
或cover?
range = 1..5
puts range.include?(3) # true
puts range.include?(6) # false
puts range.cover?(2.5) # true(在范围内)
include?
:检查是否为离散成员。cover?
:检查是否在连续范围内(对浮点数更友好)。
边界值
range = 2..7
puts range.begin # 2(起始值)
puts range.end # 7(结束值)
puts range.first # 2
puts range.last # 7
大小
puts (1..5).size # 5
puts (1...5).size # 4
4. 范围与循环
用 each
(1..3).each do |n|
puts "第 #{n} 次"
end
输出:
第 1 次
第 2 次
第 3 次
用 for
for i in 1..3
puts "计数:#{i}"
end
输出:
计数:1
计数:2
计数:3
用 times
(结合范围)
(0..2).each { |i| puts "你好 #{i}" }
输出:
你好 0
你好 1
你好 2
5. 范围与条件判断
用 case
score = 85
result = case score
when 90..100
"优秀"
when 80..89
"良好"
else
"继续努力"
end
puts result # 良好
用 include?
age = 25
if (18..30).include?(age)
puts "你是年轻人"
end
输出:
你是年轻人
6. 范围与切片
数组切片
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
puts fruits[1..2] # ["香蕉", "橙子"]
puts fruits[0...-1] # ["苹果", "香蕉", "橙子"]
字符串切片
text = "你好,世界"
puts text[0..1] # 你好
puts text[2..-1] # ,世界
7. 中文支持示例
数字范围
任务 = ["任务1", "任务2", "任务3", "任务4"]
(0..2).each do |i|
puts "执行 #{任务[i]}"
end
输出:
执行 任务1
执行 任务2
执行 任务3
实践案例
class TaskScheduler
def initialize(tasks)
@tasks = tasks
end
def run(range)
range.each do |i|
puts "执行 #{@tasks[i]}"
end
end
end
scheduler = TaskScheduler.new(["写代码", "开会", "休息"])
scheduler.run(0..1)
输出:
执行 写代码
执行 开会
8. 实践案例
案例 1:打印日期范围
require 'date'
start = Date.new(2025, 3, 22)
range = start..start + 2
range.each { |d| puts d.strftime("%Y年%m月%d日") }
输出:
2025年03月22日
2025年03月23日
2025年03月24日
案例 2:数字筛选
numbers = (1..10).to_a
even = numbers.select { |n| (2..8).include?(n) && n % 2 == 0 }
puts even # [2, 4, 6, 8]
案例 3:简单游戏
target = rand(1..10)
guess_range = 1..10
guess_range.each do |guess|
if guess == target
puts "猜中了!目标是 #{target}"
break
else
puts "猜 #{guess},不对"
end
end
输出(示例):
猜 1,不对
猜 2,不对
猜 3,猜中了!目标是 3
9. 注意事项
..
vs...
:注意包含与否:
puts (1..3).to_a # [1, 2, 3]
puts (1...3).to_a # [1, 2]
- 性能:范围是惰性对象,调用
to_a
或each
时才生成完整序列。 - 类型一致性:范围的起止值应为可比较对象(如数字、字符串)。
10. 高级用法
自定义对象范围
class Version
attr_reader :value
def initialize(value)
@value = value
end
def <=>(other)
@value <=> other.value
end
end
v1 = Version.new("1.0")
v2 = Version.new("2.0")
range = v1..v2
puts range.cover?(Version.new("1.5")) # true
无穷范围(Ruby 2.6+)
range = 1..
range.each do |n|
puts n
break if n > 3
end
输出:
1
2
3
4
下一步
- 练习:告诉我你想用范围做什么(循环、切片等),我可以设计一个例子。
- 问题解答:对范围用法有疑问吗?直接问我!
- 深入学习:想了解范围与迭代器或正则表达式的结合吗?我可以继续讲解。
你现在想做什么?写代码、问问题,还是其他?
发表回复