Ruby 条件判断
条件判断是编程中的基本控制结构,用于根据不同的条件执行不同的代码路径。Ruby提供了多种条件判断语句,使代码能够根据运行时的情况做出决策。本章将详细介绍Ruby中的各种条件判断语句及其使用方法。
🎯 条件判断基础
布尔值和真值
在Ruby中,除了false和nil之外的所有值都被视为真值(truthy):
ruby
# 真值 (truthy)
puts !!true # true
puts !!1 # true (数字)
puts !!"Hello" # true (非空字符串)
puts !![] # true (空数组)
puts !!{} # true (空哈希)
puts !!0 # true (零也是真值!)
# 假值 (falsy)
puts !!false # false
puts !!nil # false条件表达式
ruby
# 基本比较
puts 5 > 3 # true
puts 5 == 5 # true
puts "apple" < "banana" # true
# 复杂条件
age = 25
has_license = true
if age >= 18 && has_license
puts "可以开车"
end
# 字符串和数字的比较
puts "10" == 10 # false (类型不同)
puts "10" == "10" # true
puts 10 == 10 # true🔀 if语句
基本if语句
ruby
# 简单条件判断
age = 18
if age >= 18
puts "你已经成年了"
end
# if-else语句
if age >= 18
puts "成年人"
else
puts "未成年人"
end
# if-elsif-else语句
if age < 13
puts "儿童"
elsif age < 18
puts "青少年"
elsif age < 60
puts "成年人"
else
puts "老年人"
end单行if语句
ruby
# 修饰符形式的if语句
puts "成年人" if age >= 18
name = "张三"
puts "欢迎, #{name}!" if name
# 多个条件
score = 85
puts "优秀" if score >= 90
puts "良好" if score >= 80 && score < 90
puts "及格" if score >= 60 && score < 80if语句的返回值
ruby
# if语句有返回值
result = if age >= 18
"成年人"
else
"未成年人"
end
puts result # 成年人
# 更复杂的返回值
grade = 85
level = if grade >= 90
"优秀"
elsif grade >= 80
"良好"
elsif grade >= 60
"及格"
else
"不及格"
end
puts level # 良好🔁 unless语句
基本unless语句
ruby
# unless等同于if not
age = 16
unless age >= 18
puts "未成年人"
end
# unless-else语句
unless age >= 18
puts "未成年人"
else
puts "成年人"
end
# 单行unless语句
puts "未成年人" unless age >= 18unless的使用场景
ruby
# 适合用于否定条件的检查
user = nil
puts "请先登录" unless user
file_exists = File.exist?("config.txt")
puts "配置文件不存在" unless file_exists
# 避免双重否定
# 不推荐: if !user.nil?
# 推荐: unless user.nil? 或者更简洁: if user🔄 case语句
基本case语句
ruby
# 简单的case语句
grade = "B"
case grade
when "A"
puts "优秀"
when "B"
puts "良好"
when "C"
puts "及格"
else
puts "不及格"
end
# case语句的返回值
score = 85
level = case score
when 90..100
"优秀"
when 80...90
"良好"
when 60...80
"及格"
else
"不及格"
end
puts level # 良好多值匹配
ruby
# 一个when子句匹配多个值
day = "Saturday"
case day
when "Saturday", "Sunday"
puts "周末"
when "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"
puts "工作日"
end
# 使用数组进行匹配
weekend_days = ["Saturday", "Sunday"]
work_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
case day
when *weekend_days
puts "周末"
when *work_days
puts "工作日"
end范围匹配
ruby
# 使用范围进行匹配
score = 85
case score
when 90..100
puts "优秀"
when 80...90
puts "良好"
when 70...80
puts "中等"
when 60...70
puts "及格"
else
puts "不及格"
end正则表达式匹配
ruby
# 使用正则表达式进行匹配
email = "user@example.com"
case email
when /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
puts "有效的邮箱地址"
when /\A\d{11}\z/
puts "可能是手机号码"
else
puts "未知格式"
endcase语句的工作原理
ruby
# case使用===运算符进行比较
# 不同类型的对象有不同的===实现
# 数值比较
case 5
when 1..10
puts "在1到10之间"
end
# 类型检查
case "Hello"
when String
puts "这是一个字符串"
when Numeric
puts "这是一个数字"
end
# 自定义类的===方法
class Priority
def self.===(value)
value.is_a?(Integer) && value > 100
end
end
case 150
when Priority
puts "高优先级"
else
puts "普通优先级"
end🎯 三元运算符
基本语法
ruby
# 三元运算符: condition ? value_if_true : value_if_false
age = 20
status = age >= 18 ? "成年人" : "未成年人"
puts status # 成年人
# 嵌套三元运算符(谨慎使用)
score = 85
grade = score >= 90 ? "优秀" :
score >= 80 ? "良好" :
score >= 60 ? "及格" : "不及格"
puts grade # 良好三元运算符的应用场景
ruby
# 简单的条件赋值
user = nil
display_name = user ? user.name : "匿名用户"
# 或者使用更简洁的形式
display_name = user&.name || "匿名用户"
# 条件输出
debug_mode = true
puts "调试信息" if debug_mode
# 条件方法调用
class Calculator
def initialize(debug = false)
@debug = debug
end
def add(a, b)
result = a + b
puts "计算: #{a} + #{b} = #{result}" if @debug
result
end
end🔄 修饰符形式
if和unless修饰符
ruby
# if修饰符
puts "成年人" if age >= 18
raise "年龄无效" if age < 0
return unless user
# unless修饰符
puts "请登录" unless user
exit unless ready?
# 多个修饰符组合
puts "成年人且已登录" if age >= 18 && user
puts "未成年或未登录" unless age >= 18 && userwhile和until修饰符
ruby
# while修饰符
counter = 0
counter += 1 while counter < 5
puts counter # 5
# until修饰符
counter = 5
counter -= 1 until counter <= 0
puts counter # 0🎯 复杂条件判断
逻辑运算符组合
ruby
# 与运算 (&&)
user = {name: "张三", age: 25, active: true}
if user[:age] >= 18 && user[:active]
puts "#{user[:name]}可以访问"
end
# 或运算 (||)
role = "admin"
if role == "admin" || role == "moderator"
puts "具有管理权限"
end
# 非运算 (!)
logged_in = false
puts "请登录" if !logged_in
# 复杂条件组合
if (user[:age] >= 18 && user[:active]) || user[:role] == "admin"
puts "允许访问"
end短路求值
ruby
# && 短路:如果左边为false,不计算右边
def expensive_check
puts "执行昂贵检查"
true
end
false && expensive_check # 不会输出"执行昂贵检查"
# || 短路:如果左边为true,不计算右边
true || expensive_check # 不会输出"执行昂贵检查"
# 利用短路求值的安全访问
user = nil
# 安全地访问嵌套属性
name = user && user.profile && user.profile.name
# 或使用安全导航运算符 (Ruby 2.3+)
name = user&.profile&.name条件赋值
ruby
# ||= 条件赋值
cache = nil
cache ||= expensive_computation # 第一次执行计算
cache ||= another_computation # 不会执行,使用缓存值
# &&= 条件赋值
value = 10
value &&= value * 2 # value = 20
value = nil
value &&= value * 2 # value 保持为 nil🧪 条件判断实践示例
用户权限检查系统
ruby
class PermissionChecker
def initialize(user)
@user = user
end
def can_access?(resource)
# 管理员可以访问所有资源
return true if admin?
# 检查具体权限
case resource
when :public
true
when :private
logged_in?
when :admin_only
admin?
when :premium
premium_user?
else
false
end
end
def check_access(resource)
if can_access?(resource)
puts "访问授权: #{resource}"
true
else
puts "访问拒绝: #{resource}"
false
end
end
private
def logged_in?
!@user.nil?
end
def admin?
@user && @user[:role] == :admin
end
def premium_user?
@user && (@user[:role] == :premium || @user[:role] == :admin)
end
end
# 使用权限检查系统
users = [
nil, # 未登录用户
{name: "普通用户", role: :user},
{name: "高级用户", role: :premium},
{name: "管理员", role: :admin}
]
resources = [:public, :private, :premium, :admin_only]
checker = PermissionChecker.new(nil)
users.each do |user|
checker.instance_variable_set(:@user, user)
user_name = user ? user[:name] : "访客"
puts "\n=== #{user_name} ==="
resources.each do |resource|
checker.check_access(resource)
end
end成绩等级评定系统
ruby
class GradeEvaluator
def self.evaluate(score)
case score
when 90..100
"优秀"
when 80...90
"良好"
when 70...80
"中等"
when 60...70
"及格"
when 0...60
"不及格"
else
raise ArgumentError, "无效的成绩: #{score}"
end
end
def self.detailed_evaluate(score)
grade = evaluate(score)
description = case grade
when "优秀"
"表现卓越,继续保持"
when "良好"
"表现良好,还有提升空间"
when "中等"
"达到基本要求,需要努力"
when "及格"
"刚好及格,需要加强学习"
when "不及格"
"未达到要求,需要重修"
end
{
grade: grade,
score: score,
description: description
}
end
def self.batch_evaluate(scores)
results = []
scores.each_with_index do |score, index|
begin
result = detailed_evaluate(score)
result[:student_id] = index + 1
results << result
rescue ArgumentError => e
results << {
student_id: index + 1,
error: e.message
}
end
end
results
end
end
# 使用成绩评定系统
scores = [95, 87, 76, 65, 45, 105, -5]
results = GradeEvaluator.batch_evaluate(scores)
results.each do |result|
if result[:error]
puts "学生#{result[:student_id]}: #{result[:error]}"
else
puts "学生#{result[:student_id]}: #{result[:score]}分 - #{result[:grade]} - #{result[:description]}"
end
end配置文件解析器
ruby
class ConfigParser
def self.parse(config)
parsed = {}
config.each do |key, value|
parsed[key] = parse_value(key, value)
end
parsed
end
private
def self.parse_value(key, value)
case key.to_s
when /_enabled$/, /_active$/
parse_boolean(value)
when /_count$/, /_size$/, /_limit$/
parse_integer(value)
when /_timeout$/, /_delay$/
parse_float(value)
when /_list$/, /_array$/
parse_array(value)
when /_path$/
parse_path(value)
else
value # 保持原值
end
end
def self.parse_boolean(value)
case value
when true, false
value
when String
case value.downcase
when "true", "1", "yes", "on"
true
when "false", "0", "no", "off"
false
else
raise ArgumentError, "无效的布尔值: #{value}"
end
when Numeric
value != 0
else
!!value
end
end
def self.parse_integer(value)
case value
when Integer
value
when String
Integer(value)
when Float
value.to_i
else
raise ArgumentError, "无效的整数值: #{value}"
end
rescue ArgumentError
raise ArgumentError, "无效的整数值: #{value}"
end
def self.parse_float(value)
case value
when Float, Integer
value.to_f
when String
Float(value)
else
raise ArgumentError, "无效的浮点数值: #{value}"
end
rescue ArgumentError
raise ArgumentError, "无效的浮点数值: #{value}"
end
def self.parse_array(value)
case value
when Array
value
when String
value.split(",").map(&:strip)
else
[value]
end
end
def self.parse_path(value)
case value
when String
# 简单的路径清理
value.gsub(/[<>:"|?*]/, "") # 移除非法字符
else
value.to_s
end
end
end
# 使用配置解析器
config = {
debug_enabled: "true",
max_connections: "100",
request_timeout: "30.5",
allowed_hosts: "localhost,127.0.0.1,example.com",
log_path: "/var/log/app.log",
cache_size: 1024
}
begin
parsed_config = ConfigParser.parse(config)
parsed_config.each do |key, value|
puts "#{key}: #{value} (#{value.class})"
end
rescue ArgumentError => e
puts "配置解析错误: #{e.message}"
end🎯 条件判断最佳实践
1. 保持条件简单
ruby
# 好的做法:将复杂条件提取为方法
class UserValidator
def self.valid_user?(user)
user &&
user.active? &&
user.email_verified? &&
user.age >= 18
end
def self.premium_user?(user)
valid_user?(user) && user.subscription == "premium"
end
end
# 使用
if UserValidator.premium_user?(user)
# 处理高级用户
end2. 合理使用case语句
ruby
# 好的做法:多个离散值使用case
case action
when "create"
create_resource
when "update"
update_resource
when "delete"
delete_resource
else
raise ArgumentError, "未知操作: #{action}"
end
# 避免:简单条件使用case
# 不推荐:
case
when score >= 90
puts "优秀"
when score >= 80
puts "良好"
end
# 推荐:
if score >= 90
puts "优秀"
elsif score >= 80
puts "良好"
end3. 避免深层嵌套
ruby
# 不好的做法:深层嵌套
if user
if user.active?
if user.age >= 18
if user.subscription == "premium"
# 处理逻辑
end
end
end
end
# 好的做法:早期返回
def process_user(user)
return unless user
return unless user.active?
return unless user.age >= 18
return unless user.subscription == "premium"
# 处理逻辑
end
# 或者合并条件
def process_user(user)
if user && user.active? && user.age >= 18 && user.subscription == "premium"
# 处理逻辑
end
end4. 使用安全导航运算符
ruby
# 旧方式:多重nil检查
if user && user.profile && user.profile.address && user.profile.address.city
puts user.profile.address.city
end
# 新方式:安全导航运算符 (Ruby 2.3+)
puts user&.profile&.address&.city
# 结合条件赋值
city = user&.profile&.address&.city || "未知城市"📚 下一步学习
掌握了Ruby条件判断后,建议继续学习:
继续您的Ruby学习之旅吧!