ruby可变参数

在 Ruby 中,可变参数是一种灵活处理方法参数的机制,允许方法接受不确定数量的参数。以下是详细的用法和规则:


一、基础用法:*args 收集剩余参数

* 符号声明可变参数,会将多余的位置参数收集为数组。

1. 简单示例
ruby 复制代码
def sum(*numbers)
  numbers.sum
end

sum(1, 2, 3)     # => 6
sum(10)           # => 10
sum               # => 0(空数组)
2. 混合位置参数与可变参数
ruby 复制代码
def greet(greeting, *names)
  names.each { |name| puts "#{greeting}, #{name}!" }
end

greet("Hello", "Alice", "Bob")
# 输出:
# Hello, Alice!
# Hello, Bob!

二、参数顺序规则

1. 必须参数的优先级
ruby 复制代码
def demo(a, b, *args)
  [a, b, args]
end

demo(1, 2, 3, 4)  # => [1, 2, [3, 4]]
demo(1, 2)        # => [1, 2, []]
# demo(1)         # 错误:缺少参数 b
2. 默认参数与可变参数的结合
ruby 复制代码
def demo(a = 0, b = 1, *args)
  [a, b, args]
end

demo           # => [0, 1, []]
demo(5)        # => [5, 1, []]
demo(5, 6, 7)  # => [5, 6, [7]]

三、解包数组作为参数 (* 的逆操作)

在方法调用时,用 * 解包数组为多个参数。

ruby 复制代码
def print_values(a, b, c)
  puts "#{a}, #{b}, #{c}"
end

arr = [1, 2, 3]
print_values(*arr)  # 输出 "1, 2, 3"

# 自动裁剪多余元素
arr = [1, 2, 3, 4]
print_values(*arr)  # 输出 "1, 2, 3"

四、关键字参数与 **kwargs

** 收集未声明的关键字参数为哈希。

1. 基础用法
ruby 复制代码
def user_info(name, **options)
  { name: name, **options }
end

user_info("Alice", age: 20, role: "admin")
# => { name: "Alice", age: 20, role: "admin" }
2. 解包哈希作为关键字参数
ruby 复制代码
def connect(host:, port: 80)
  "Connecting to #{host}:#{port}"
end

params = { host: "example.com", port: 3000 }
connect(**params)  # => "Connecting to example.com:3000"

五、混合所有参数类型

Ruby 允许组合多种参数类型,但需遵循严格顺序:
位置参数 → 默认参数 → 可变参数 → 关键字参数 → 关键字可变参数

1. 完整示例
ruby 复制代码
def complex_method(a, b=2, *args, c:, d: 4, **kwargs)
  { a: a, b: b, args: args, c: c, d: d, kwargs: kwargs }
end

complex_method(1, 3, 4, 5, c: 6, e: 7)
# => { a: 1, b: 3, args: [4, 5], c: 6, d: 4, kwargs: { e: 7 } }
2. 非法组合示例
ruby 复制代码
# 错误:可变参数 (*args) 必须在关键字参数之前
def invalid(a, *args, b: 1)
end

六、特殊场景与技巧

1. 强制要求至少一个可变参数
ruby 复制代码
def at_least_one(*args)
  raise ArgumentError if args.empty?
  # 其他逻辑
end
2. 忽略多余参数
ruby 复制代码
def ignore_extra(*)
  # 不处理多余参数
end
ignore_extra(1, 2, 3)  # 无错误

七、代码块参数 (&block)

虽然与可变参数无关,但常结合使用:

ruby 复制代码
def wrap_method(*args, &block)
  puts "Args: #{args}"
  block.call if block_given?
end

wrap_method(1, 2) { puts "Block!" }
# 输出:
# Args: [1, 2]
# Block!

总结:Ruby 参数处理优先级

  1. 位置参数 (必须参数 → 默认参数 → 可变参数 *args
  2. 关键字参数 (显式关键字 → 默认关键字 → 关键字可变参数 **kwargs
  3. 代码块参数 (&block)

掌握可变参数机制,可以编写出高度灵活且健壮的 Ruby 方法。

相关推荐
chao_78928 分钟前
QT开发工具对比:Qt Creator、Qt Designer、Qt Design Studio
开发语言·qt
lh_125437 分钟前
Uni-app 组件使用
前端·javascript·uni-app
Kx…………42 分钟前
Day3:设置页面全局渐变线性渐变背景色uniapp壁纸实战
前端·学习·uni-app·实战·项目
Q_Boom1 小时前
前端跨域问题怎么在后端解决
java·前端·后端·spring
搬砖工程师Cola1 小时前
<Revit二次开发> 通过一组模型线构成墙面,并生成墙。Create(Document, IList.Curve., Boolean)
java·前端·javascript
林十一npc1 小时前
Fiddler抓取APP端,HTTPS报错全解析及解决方案(一篇解决常见问题)
android·前端·网络协议·https·fiddler·接口测试
小妖6662 小时前
4个纯CSS自定义的简单而优雅的滚动条样式
前端·javascript·css
浪前2 小时前
【项目篇之统一内存操作】仿照RabbitMQ模拟实现消息队列
java·分布式·rabbitmq·ruby
珊瑚里的鱼2 小时前
LeetCode 102题解 | 二叉树的层序遍历
开发语言·c++·笔记·算法·leetcode·职场和发展·stl
江沉晚呤时2 小时前
深入解析 .NET Kestrel:高性能 Web 服务器的架构与最佳实践
服务器·前端·.net