好的!以下是关于 Ruby 方法 的详细讲解。方法是 Ruby 中定义行为的核心机制,广泛用于封装逻辑、操作数据和实现功能。我会介绍方法的定义、参数、返回值等特性,结合中文示例和实践案例,帮助你掌握 Ruby 方法的用法。


1. 什么是方法?

方法是一段命名的、可重用的代码块,可以接受参数并返回结果。在 Ruby 中:

  • 方法用 def 定义。
  • 方法名通常小写,用下划线分隔单词(例如 say_hello)。
  • 方法是对象行为的基础,常定义在类中。

2. 定义方法

基本语法

def 方法名
  # 代码块
end

示例

def say_hello
  "你好,世界!"
end

puts say_hello  # 你好,世界!

注意

  • 方法默认返回最后一行表达式的值,无需显式 return(但可以用)。
  • 方法名支持中文:
  def 你好
    "大家好!"
  end
  puts 你好  # 大家好!

3. 方法参数

普通参数

def greet(name)
  "你好,#{name}!"
end

puts greet("张三")  # 你好,张三!

默认参数

参数可以有默认值,避免调用时必须传参。

def greet(name = "朋友")
  "你好,#{name}!"
end

puts greet        # 你好,朋友!
puts greet("李四")  # 你好,李四!

可变参数(*

* 收集多个参数为数组。

def sum(*numbers)
  numbers.sum
end

puts sum(1, 2, 3)      # 6
puts sum(10, 20, 30, 40)  # 100

关键字参数

: 定义具名参数,避免顺序问题。

def introduce(name:, age:)
  "我叫 #{name},#{age} 岁。"
end

puts introduce(name: "王五", age: 25)  # 我叫 王五,25 岁。
# puts introduce("王五", 25)  # 错误:缺少关键字

可选关键字参数

def describe(name:, age: 18)
  "姓名:#{name},年龄:#{age}"
end

puts describe(name: "赵六")        # 姓名:赵六,年龄:18
puts describe(name: "赵六", age: 30)  # 姓名:赵六,年龄:30

4. 返回值

隐式返回

Ruby 自动返回最后一行:

def add(a, b)
  a + b
end

puts add(5, 3)  # 8

显式返回

return 指定返回值,并立即退出方法:

def check_age(age)
  return "未成年" if age < 18
  "成年"
end

puts check_age(16)  # 未成年
puts check_age(20)  # 成年

多值返回

返回数组,解构赋值:

def split_name(full_name)
  [full_name[0], full_name[1..-1]]
end

姓, 名 = split_name("张三")
puts "姓:#{姓},名:#{名}"  # 姓:张,名:三

5. 方法修饰符

方法名后缀

  • ?:返回布尔值(惯例):
  def adult?(age)
    age >= 18
  end
  puts adult?(20)  # true
  • !:表示修改对象(破坏性方法,惯例):
  def shout!(text)
    text.upcase!
  end
  word = "hello"
  shout!(word)
  puts word  # HELLO

私有方法

private 限制外部访问:

class Person
  def initialize(name)
    @name = name
  end

  def greet
    secret_info  # 调用私有方法
  end

  private
  def secret_info
    "我的名字是 #{@name}"
  end
end

p = Person.new("张三")
puts p.greet      # 我的名字是 张三
# p.secret_info   # 错误:私有方法

6. 类方法

类方法属于类本身,用 self. 定义。

示例

class Calculator
  def self.add(a, b)
    a + b
  end
end

puts Calculator.add(5, 3)  # 8

替代写法

class << self
  def subtract(a, b)
    a - b
  end
end

puts Calculator.subtract(10, 7)  # 3

7. 中文支持示例

方法名和参数支持中文:

class 学生
  def initialize(姓名)
    @姓名 = 姓名
  end

  def 自我介绍
    "大家好,我是 #{@姓名}!"
  end
end

学生1 = 学生.new("李四")
puts 学生1.自我介绍  # 大家好,我是 李四!

8. 实践案例

案例 1:温度转换器

class Temperature
  def initialize(摄氏度)
    @摄氏度 = 摄氏度
  end

  def 转为华氏度
    (@摄氏度 * 9 / 5) + 32
  end

  def self.冰点
    0
  end
end

temp = Temperature.new(25)
puts temp.转为华氏度      # 77
puts Temperature.冰点    # 0

案例 2:购物清单

class ShoppingList
  def initialize
    @items = []
  end

  def 添加(*商品)
    @items.concat(商品)
    "已添加:#{商品.join(', ')}"
  end

  def 显示
    @items.empty? ? "清单为空" : @items.join("\n")
  end
end

清单 = ShoppingList.new
puts 清单.添加("牛奶", "面包")  # 已添加:牛奶, 面包
puts 清单.显示
# 牛奶
# 面包

案例 3:简单游戏计分

class Game
  def initialize
    @score = 0
  end

  def 加分(points = 10)
    @score += points
    "得分增加 #{points},当前得分:#{@score}"
  end

  def 重置!
    @score = 0
    "得分已重置"
  end
end

game = Game.new
puts game.加分      # 得分增加 10,当前得分:10
puts game.加分(20)  # 得分增加 20,当前得分:30
puts game.重置!     # 得分已重置

9. 注意事项

  • 参数顺序:普通参数、可变参数、关键字参数需按顺序定义:
  def example(a, *b, key:)
    # 正确
  end
  • 返回值:方法总是返回一个值(默认最后一行或 nil)。
  • 作用域:方法内部的局部变量不会影响外部。

下一步

  • 练习:告诉我你想练习哪种方法(带参数、类方法等),我可以设计一个例子。
  • 问题解答:对方法定义或用法有疑问吗?直接问我!
  • 深入学习:想了解方法重载、块参数或 Proc/Lambda 吗?我可以继续讲解。

你现在想做什么?写代码、问问题,还是其他?