【KWDB 创作者计划】_ruby基础语法

news2025/4/13 11:10:07

以下是 Ruby 基础语法的简明总结,适合快速入门:


一、变量与常量

1. 局部变量

小写字母或下划线开头,作用域为当前代码块。

name = "Alice"
_age = 20

//局部变量附加:{{{{

声明与命名规则

  1. 命名格式

    • 以小写字母或下划线 _ 开头,如 name_count
    • 后续字符可包含字母、数字和下划线。
    • 避免与 Ruby 关键字(如 classdef)冲突。
  2. 声明方式

    • 通过赋值 = 隐式声明,无需显式类型。
    age = 25           # 声明局部变量 age
    _message = "Hello" # 声明局部变量 _message
    

作用域规则

  1. 代码块内外的可见性

    • 块参数会遮蔽外部变量

      x = 10
      3.times do |x|    # 块参数 x 遮蔽外部变量
        puts x          # 输出 0, 1, 2
      end
      puts x            # 输出 10(外部变量未被修改)
      
    • 无块参数时可访问外部变量

      x = 5
      3.times do
        x = 10         # 修改外部变量 x
      end
      puts x            # 输出 10
      
  2. 方法内的局部变量

    • 方法内部变量对外不可见:

      def test_method
        local_var = "内部变量"
      end
      test_method
      puts local_var    # NameError: undefined local variable
      
    • 方法无法访问定义它的外部局部变量:

      outer_var = "外部变量"
      def show_var
        puts outer_var  # NameError: undefined local variable
      end
      show_var
      
  3. 条件与循环中的变量

    • 即使条件未执行,变量也会被声明(初始化为 nil):

      if false
        a = 1          # 代码未执行,但变量 a 已声明
      end
      puts a            # 输出 nil
      
    • 循环(如 while)不创建新作用域:

      i = 0
      while i < 3
        inner = i
        i += 1
      end
      puts inner        # 输出 2
      

变量遮蔽与覆盖

  1. 内部作用域遮蔽外部变量

    x = 100
    1.times do
      x = 200          # 直接修改外部变量 x
      y = 300          # 声明新变量 y(作用域在块内)
    end
    puts x             # 输出 200
    puts y             # NameError: undefined local variable
    
  2. 方法参数与局部变量同名

    def demo(x)
      x = 20           # 修改的是参数 x,不影响外部变量
      puts x           # 输出 20
    end
    x = 10
    demo(x)
    puts x             # 输出 10
    

特殊场景

  1. 顶层作用域的局部变量

    • 在文件或交互式环境(如 irb)顶层定义的局部变量,作用域为当前文件或会话:
      top_var = "顶层变量"
      def show_top_var
        puts top_var   # NameError: undefined local variable
      end
      show_top_var
      
  2. 类/模块定义中的局部变量

    • 在类或模块定义中声明的局部变量,仅在该定义范围内有效:
      class MyClass
        class_var = "类定义内的局部变量"
        def self.show_var
          puts class_var # NameError: undefined local variable
        end
      end
      

最佳实践

  1. 避免变量遮蔽:谨慎使用与外部作用域同名的变量。
  2. 限制作用域:在最小必要范围内定义变量,减少副作用。
  3. 明确命名:使用有意义的变量名(如 user_count 而非 uc)。

总结

场景行为
块内无参数赋值可读写外部变量
块带同名参数遮蔽外部变量,内部操作不影响外部
方法内部变量仅在方法内有效,外部不可见
条件/循环中的变量即使代码未执行,变量也会被声明(值为 nil
类定义中的变量仅在类定义过程中有效,类方法无法访问

理解局部变量的作用域规则是编写可维护 Ruby 代码的基础,尤其在处理复杂逻辑时能避免意外的变量污染或覆盖。

//局部变量附加结束}}}}

2. 实例变量

@ 开头,属于对象实例。

@name = "Bob"

//实例变量附加:{{{{
实例变量(Instance Variables)是面向对象编程的核心概念,用于存储对象的状态。以下是其详细规则和使用方法:

定义与基本特性

  1. 命名规则

    • @ 符号开头,如 @name@age
    • 后续字符可包含字母、数字和下划线。
    • 默认值为 nil(未显式赋值时)。
  2. 作用域

    • 属于对象实例:每个对象的实例变量独立存在。
    • 在类的方法中可访问:在类的任何实例方法中均可读写。

声明与访问

  1. 直接赋值
class Person
  def initialize(name)
    @name = name  # 在 initialize 方法中初始化
  end

  def greet
    "Hello, #{@name}!"  # 在方法中访问
  end
end

person = Person.new("Alice")
puts person.greet  # => "Hello, Alice!"

//class Person代码的解释开始:
这段 Ruby 脚本定义了一个 Person 类,并演示了如何创建对象实例和调用方法。以下是逐行解释:

  1. 定义 Person
class Person
  # 类体开始
end
  • class Person:定义一个名为 Person 的类。
  • Ruby 的类名需以 大写字母开头,采用驼峰式命名。
  1. 构造方法 initialize
def initialize(name)
  @name = name  # 初始化实例变量 @name
end
  • initialize:类的构造方法,在调用 Person.new 时自动执行。
  • name:构造方法的参数,用于接收外部传入的值。
  • @name = name:将参数 name 赋值给实例变量 @name
    • @name:以 @ 开头的变量是实例变量,属于对象实例的私有状态。
  1. 实例方法 greet
def greet
  "Hello, #{@name}!"  # 使用实例变量 @name 拼接字符串
end
  • greet:定义一个名为 greet 的实例方法。
  • #{@name}:字符串插值语法,将 @name 的值嵌入字符串中。
  • 方法返回值为字符串(Ruby 中方法的最后一行的值会被自动返回)。
  1. 创建对象实例
person = Person.new("Alice")
  • Person.new("Alice"):调用 Person 类的 new 方法创建实例。
    • new 方法会触发 initialize 方法,并将 "Alice" 作为参数传递。
    • 此时 @name 被赋值为 "Alice"
  • person:变量指向新创建的 Person 实例对象。
  1. 调用方法并输出结果
puts person.greet  # => "Hello, Alice!"
  • person.greet:调用 person 实例的 greet 方法。
    • 方法返回字符串 "Hello, Alice!"
  • puts:输出字符串到控制台。

//class Person代码的解释结束

  1. 通过访问器方法
    Ruby 提供快捷方法生成 gettersetter
  • attr_reader:生成 getter 方法。
  • attr_writer:生成 setter 方法。
  • attr_accessor:生成 getter 和 setter。
class User
  attr_accessor :email  # 自动生成 @email 的读写方法
  attr_reader :id       # 只生成 @id 的读方法

  def initialize(id)
    @id = id
  end
end

user = User.new(1)
user.email = "alice@example.com"
puts user.email  # => "alice@example.com"

//访问器方法代码解释 开始
属性访问器(Attribute Accessors),属性访问器(Attribute Accessors)是一种元编程机制,用于快速生成实例变量的 getter(读方法)和 setter(写方法)。Ruby 提供了三个核心方法简化操作:
三种属性访问器

  1. attr_reader
    生成 只读方法(getter),允许外部读取实例变量。

    class User
      attr_reader :id  # 生成 def id; @id; end
    
      def initialize(id)
        @id = id
      end
    end
    
    user = User.new(1)
    puts user.id   # => 1
    user.id = 2    # NoMethodError(无写方法)
    
  2. attr_writer
    生成 只写方法(setter),允许外部修改实例变量。

    class User
      attr_writer :email  # 生成 def email=(value); @email = value; end
    
      def initialize(email)
        @email = email
      end
    end
    
    user = User.new("alice@example.com")
    user.email = "bob@example.com"  # 修改成功
    puts user.email                 # NoMethodError(无读方法)
    
  3. attr_accessor
    生成 读写方法(getter + setter),最常用。

    class Product
      attr_accessor :price  # 生成读方法和写方法
    
      def initialize(price)
        @price = price
      end
    end
    
    product = Product.new(100)
    product.price = 150
    puts product.price  # => 150
    

访问器的底层原理

  1. 手动实现等效代码

    class User
      # attr_reader :name 的等效代码
      def name
        @name
      end
    
      # attr_writer :name 的等效代码
      def name=(value)
        @name = value
      end
    end
    
  2. 动态生成方法
    attr_* 方法本质是通过元编程动态定义方法:

    class Class
      def my_attr_reader(name)
        define_method(name) do
          instance_variable_get("@#{name}")
        end
      end
    end
    

高级用法与技巧

  1. 批量定义访问器

    class Person
      attr_accessor :name, :age, :gender  # 多个属性
    end
    
  2. 添加自定义逻辑

    class Temperature
      attr_reader :celsius
    
      def celsius=(value)
        raise "温度不能低于绝对零度" if value < -273.15
        @celsius = value
      end
    end
    
    temp = Temperature.new
    temp.celsius = -300  # RuntimeError
    
  3. 结合初始化方法

    class Book
      attr_accessor :title, :author
    
      def initialize(title, author)
        @title = title
        @author = author
      end
    end
    
    book = Book.new("Ruby指南", "松本行弘")
    book.title = "Ruby高级编程"
    
  4. 继承行为
    父类的访问器方法会被子类继承:

    class Admin < User
    end
    admin = Admin.new(1)
    admin.email = "admin@example.com"  # 正常执行(继承 attr_accessor)
    

//访问器方法代码解释 结束

实例变量的特性

  1. 封装性
  • 实例变量默认是 私有 的,外部无法直接访问。
  • 必须通过方法暴露(如 attr_accessor)。
  1. 动态增删
    可在运行时动态添加或删除实例变量:
obj = Object.new
obj.instance_variable_set(:@x, 10)  # 动态添加 @x
puts obj.instance_variable_get(:@x) # => 10
obj.remove_instance_variable(:@x)   # 删除 @x

//动态增删附加 开始:
这段 Ruby 脚本演示了如何通过反射机制 动态管理实例变量
代码逐行解析

  1. 创建新对象
obj = Object.new
  • 作用:创建一个 Object 类的匿名实例。
  • 对象状态:此时 obj 没有任何预定义的实例变量。
  1. 动态添加实例变量 @x
obj.instance_variable_set(:@x, 10)
  • instance_variable_set 方法
    • 功能:直接为对象设置实例变量。
    • 参数
      • 第一个参数:符号形式的变量名(必须包含 @,如 :@x)。
      • 第二个参数:变量值(可以是任意对象)。
    • 结果:对象 obj 新增实例变量 @x,值为 10
  1. 读取实例变量 @x 的值
puts obj.instance_variable_get(:@x) # => 10
  • instance_variable_get 方法
    • 功能:直接读取对象的实例变量值。
    • 参数:符号形式的变量名(如 :@x)。
    • 返回值:变量的当前值,若变量不存在则返回 nil
  1. 删除实例变量 @x
obj.remove_instance_variable(:@x)
  • remove_instance_variable 方法
    • 功能:从对象中删除指定的实例变量。
    • 参数:符号形式的变量名(如 :@x)。
    • 返回值:被删除变量的值。
    • 注意:若变量不存在会抛出 NameError

关键方法和注意事项

方法名用途注意事项
instance_variable_set动态设置实例变量变量名必须@ 开头,否则抛出 NameError
instance_variable_get动态读取实例变量变量不存在时返回 nil,不会报错
remove_instance_variable动态删除实例变量变量不存在时抛出 NameError,需确保变量存在或使用 begin rescue 处理

使用场景

  1. 动态对象构造
    在运行时根据条件动态添加属性:

    data = { name: "Alice", age: 20 }
    obj = Object.new
    data.each { |key, value| obj.instance_variable_set("@#{key}", value) }
    
  2. 元编程和框架开发
    在编写灵活的程序结构时(如 ORM、序列化工具):

    class Serializer
      def serialize(obj)
        obj.instance_variables.each_with_object({}) do |var, hash|
          hash[var] = obj.instance_variable_get(var)
        end
      end
    end
    
  3. 调试和探索性编程
    快速查看或修改对象内部状态:

    user = User.find(1)
    user.instance_variable_set(:@password, "hacked") # 危险操作!仅用于演示
    obj = Object.new
    obj.instance_variable_set(:@不存在的方法, 100) # 合法但可能导致后续逻辑混乱
    
    # 使用下判断
    if obj.instance_variable_defined?(:@x)
      obj.remove_instance_variable(:@x)
    end
    

// 动态增删附加 结束

  1. 与类变量的对比
实例变量 (@var)类变量 (@@var)
作用域对象实例内类及其所有实例共享
继承行为子类对象不继承父类实例变量子类共享父类的类变量

高级用法
5. 元编程访问

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

dog = Dog.new("Buddy")

# 获取所有实例变量名
dog.instance_variables  # => [:@name]

# 检查是否存在实例变量
dog.instance_variable_defined?(:@name)  # => true
  1. 在模块中定义实例变量
module Loggable
  def log(message)
    @logs ||= []  # 若 @logs 不存在则初始化为空数组
    @logs << message
  end
end

class Service
  include Loggable
end

service = Service.new
service.log("Event 1")
service.instance_variable_get(:@logs)  # => ["Event 1"]

注意事项

  1. 避免未初始化访问
    实例变量未赋值时为 nil,需注意空值问题:

    class Product
      def print_price
        "Price: #{@price}"  # @price 未初始化时为 nil
      end
    end
    
    Product.new.print_price  # => "Price: "
    
  2. 命名冲突
    子类可能意外覆盖父类的实例变量:

    class Animal
      def initialize
        @name = "Animal"
      end
    end
    
    class Cat < Animal
      def initialize
        @name = "Cat"  # 覆盖父类的 @name
      end
    end
    

总结

场景实例变量的行为
对象初始化通过 initialize 方法赋值
方法间共享同一对象的实例方法均可访问
动态管理支持运行时增删
封装性必须通过方法暴露给外部

实例变量是 Ruby 面向对象的核心机制,合理使用它们可以高效管理对象状态!

//实例变量附加结束}}}}

3. 类变量

@@ 开头,属于整个类。

@@count = 0

// 类变量 附加开始{{{{
在 Ruby 中,类变量(Class Variables)是一种特殊类型的变量,用于在类层级共享数据。

定义与基本特性

  1. 命名规则

    • @@ 开头,如 @@count@@config
    • 后续字符遵循变量命名规范(字母、数字、下划线)。
    • 必须显式初始化(否则抛出 NameError)。
  2. 作用域

    • 类层级共享:类变量属于类本身,被所有实例和子类共享。
    • 全局可见:在类定义、实例方法、类方法中均可访问。

基本用法示例

1. 类变量初始化与访问
class Counter
  @@count = 0  # 初始化类变量

  def self.increment
    @@count += 1
  end

  def self.total
    @@count
  end
end

Counter.increment
Counter.increment
puts Counter.total  # => 2
  1. 实例方法访问类变量
class User
  @@users = []

  def initialize(name)
    @name = name
    @@users << self  # 将实例自身加入类变量数组
  end

  def self.all_users
    @@users
  end
end

alice = User.new("Alice")
bob = User.new("Bob")
puts User.all_users.size  # => 2

类变量的继承行为

  1. 子类共享父类的类变量
class Parent
  @@value = 100

  def self.value
    @@value
  end
end

class Child < Parent
  def self.change_value
    @@value = 200
  end
end

Child.change_value
puts Parent.value  # => 200(父类的类变量被子类修改)
  1. 所有子类共享同一变量
class A
  @@list = []
end

class B < A; end
class C < A; end

B.class_variable_get(:@@list) << "item"
puts C.class_variable_get(:@@list)  # => ["item"]

类变量的替代方案:类实例变量
由于类变量的共享特性容易导致意外修改,Ruby 开发者常使用 类实例变量 作为替代:

  1. 类实例变量特性
  • @ 开头,属于类对象(而非类本身)。
  • 不被子类继承,每个类独立拥有自己的副本。
  • 通过类方法中的 attr_accessor 定义。
  1. 示例对比
class Parent
  @count = 0  # 类实例变量

  class << self
    attr_accessor :count  # 定义类实例变量的访问器
  end
end

class Child < Parent; end

Parent.count = 5
Child.count = 10
puts Parent.count  # => 5(不受子类影响)
puts Child.count   # => 10

类变量使用场景

场景示例
全局类级计数器统计实例数量、方法调用次数
共享配置数据库连接、日志级别设置
缓存数据存储类级别的计算结果或临时数据

注意事项与陷阱

  1. 初始化位置
    类变量必须在类或模块内部初始化(不能在其他作用域)。

    class Demo
      @@value = 0  # 正确:在类体内初始化
    end
    
    # @@value = 0  # 错误:顶层作用域无法初始化类变量
    
  2. 线程安全问题
    类变量在多线程环境中可能引发竞态条件,需加锁保护:

    class Counter
      @@mutex = Mutex.new
      @@count = 0
    
      def self.safe_increment
        @@mutex.synchronize { @@count += 1 }
      end
    end
    
  3. 避免过度共享
    类变量的全局性容易导致代码耦合,应谨慎使用。

总结对比

特性类变量 (@@var)类实例变量 (@var)
作用域类及其所有子类共享仅在定义它的类中有效
继承行为子类修改影响父类和其他子类不继承,每个类独立
初始化位置必须在类或模块内部可在类方法或类体内初始化
适用场景需要跨继承树共享数据需要类级别的私有状态

//类变量 附加结束}}}}

4. 全局变量

$ 开头,作用域全局。

$debug_mode = true

//全局变量附件开始
全局变量(Global Variables)是作用域覆盖整个程序(包括所有模块、类和方法的变量)。

全局变量的核心规则

  1. 命名规则

    • $ 开头,如 $counter$logger
    • 后续字符遵循变量命名规范(字母、数字、下划线)。
  2. 作用域

    • 全局可见:在程序的任何位置(包括类、模块、方法、块)均可读写。
  3. 默认值

    • 未初始化的全局变量值为 nil

基本用法示例

  1. 声明与赋值
$app_name = "MyApp"  # 定义全局变量

class User
  def print_app_name
    puts $app_name  # 在类内访问全局变量
  end
end

def log_message
  $app_name = "NewApp"  # 在方法内修改全局变量
end

log_message
User.new.print_app_name  # 输出 "NewApp"
  1. 预定义全局变量
    Ruby 有一些内置的全局变量(如 $!$@),用于访问系统信息或异常上下文:
begin
  1 / 0
rescue => e
  puts $!  # 输出最后抛出的异常信息(等同 e.message)
  puts $@  # 输出异常堆栈跟踪(等同 e.backtrace)
end

全局变量的优缺点
优点

  • 快速共享数据:无需通过参数传递,直接跨作用域访问。
  • 临时调试工具:快速记录程序状态。

缺点

  • 破坏封装性:导致代码耦合,难以追踪修改来源。
  • 命名冲突风险:全局变量名可能被意外覆盖。
  • 维护困难:大型项目中难以管理。

使用场景(谨慎选择!)

场景示例
跨模块共享配置日志级别、环境变量
临时调试或性能监控记录方法调用次数
单例模式简单实现全局唯一的数据库连接对象

替代方案(推荐优先使用)

  1. 常量(全大写命名)

    module Config
      APP_NAME = "MyApp"  # 常量,可被修改但会警告
    end
    
    puts Config::APP_NAME
    
  2. 类/模块变量

    class AppState
      @@instance_count = 0  # 类变量
    
      def self.increment
        @@instance_count += 1
      end
    end
    
  3. 单例模式

    require 'singleton'
    
    class Logger
      include Singleton
      attr_accessor :level
    
      def initialize
        @level = "INFO"
      end
    end
    
    Logger.instance.level = "DEBUG"
    

注意事项

  1. 避免滥用:仅在无其他替代方案时使用。

  2. 命名规范:使用明确的前缀(如 $myapp_logger),避免与内置全局变量冲突。

  3. 线程安全:多线程环境中需加锁保护。

    $counter = 0
    $counter_mutex = Mutex.new
    
    def increment_counter
      $counter_mutex.synchronize { $counter += 1 }
    end
    
  4. 重置全局变量:可通过赋值 nil 释放资源。

    $db_connection = nil  # 断开数据库连接并释放内存
    

内置全局变量

变量用途
$!最后抛出的异常对象
$@最后异常的堆栈跟踪信息
$?最后执行的子进程状态
$0当前执行的脚本文件名
$:Ruby 的加载路径(等同 $LOAD_PATH
$_最后读取的输入行(如 gets 结果)

最佳实践:除非必要,优先使用常量、类变量或依赖注入模式替代全局变量。
//全局变量附件结束

5. 常量

全大写字母,约定不可修改(修改会警告)。

PI = 3.14159

//常量附加开始
常量(Constants)是一种用于存储固定值的标识符,其命名以大写字母开头,通常用于定义配置、枚举值或全局共享数据。

常量的基本规则

  1. 命名规范

    • 必须以大写字母开头(如 PIMAX_SIZE)。
    • 约定全大写加下划线(如 DEFAULT_TIMEOUT),但也可用驼峰式(如 AppConfig)。
  2. 赋值与修改

    • 应保持不可变:Ruby 允许修改常量,但会发出警告。
    • 重新赋值触发警告:
      PI = 3.14
      PI = 3.14159  # 输出 warning: already initialized constant PI
      
  3. 作用域

    • 定义在类、模块或顶层作用域。
    • 通过命名空间访问(如 MyClass::CONST)。

常量的定义与访问

  1. 顶层常量(全局可见)
APP_NAME = "MyApp"  # 顶层常量

class User
  def show_app_name
    APP_NAME  # 直接访问
  end
end

puts APP_NAME  # => "MyApp"
  1. 类/模块内的常量
class MathUtils
  PI = 3.14159  # 类常量

  def circle_area(radius)
    PI * radius ** 2
  end
end

puts MathUtils::PI  # => 3.14159
  1. 模块中的常量
module Colors
  RED = "#FF0000"
end

class Car
  include Colors
end

puts Car::RED  # => "#FF0000"(通过 include 引入)

常量的查找规则

  1. 继承链查找
    子类会继承父类的常量,但可覆盖:
class Parent
  VALUE = 100
end

class Child < Parent
  VALUE = 200  # 覆盖父类常量
end

puts Parent::VALUE  # => 100
puts Child::VALUE    # => 200
  1. 作用域解析运算符 ::
module Outer
  CONST = "Outer"
  module Inner
    CONST = "Inner"
    def self.show
      puts CONST         # => "Inner"
      puts Outer::CONST  # => "Outer"
    end
  end
end

Outer::Inner.show

常量 vs 类变量

特性常量 (CONST)类变量 (@@var)
命名规则大写字母开头@@ 开头
可修改性可修改(有警告)可随意修改
作用域类/模块或全局类及其子类共享
继承行为子类可覆盖子类共享同一变量

最佳实践

  1. 避免修改常量
    如需可变配置,改用类方法或单例模式:

    class Config
      def self.timeout
        @timeout ||= 10  # 可修改且无警告
      end
    end
    
  2. 冻结常量(不可变对象)
    防止常量引用的对象被修改:

    COLORS = { red: "#FF0000" }.freeze
    COLORS[:red] = "#FF1234"  # RuntimeError: can't modify frozen Hash
    
  3. 使用模块组织常量

    module Settings
      TIMEOUT = 30
      API_KEY = "secret"
    end
    
    puts Settings::API_KEY
    

动态操作常量

  1. 动态定义与访问
class Dynamic
  const_set(:MAX, 100)         # 定义常量 MAX
  puts const_get(:MAX)         # => 100
  puts constants.include?(:MAX) # => true
end
  1. 检查常量存在性
if MyClass.const_defined?(:VERSION)
  puts MyClass::VERSION
end

常见错误

  1. 未初始化的常量

    puts UNDEFINED_CONST  # NameError: uninitialized constant UNDEFINED_CONST
    
  2. 命名空间遗漏

    module A
      module B
        CONST = 1
      end
    end
    puts B::CONST  # NameError: uninitialized constant B(需写 A::B::CONST)
    

//常量附加结束


二、数据类型

1. 数值(Numberic)

以下是 Ruby 中 数值类型(Numeric) 的详细解析,涵盖整数、浮点数、数值运算、类型转换以及实用技巧。

数值类型分类
Ruby 的数值类型分为 整数浮点数,所有数值均为对象,属于 Numeric 类的子类。

类型类名说明示例
整数Integer包括小整数(Fixnum)和大整数(Bignum),Ruby 自动处理类型转换42, 12345678901234567890
浮点数Float双精度浮点数,遵循 IEEE 754 标准3.14, 6.022e23
有理数Rational精确分数(需手动创建或引入库)Rational(3, 4) => 3/4
复数Complex复数类型(需手动创建或引入库)Complex(2, 3) => 2+3i

整数(Integer)

  1. 表示方式
  • 十进制:默认写法,如 123
  • 二进制:以 0b0B 开头,如 0b1010(十进制的 10)。
  • 八进制:以 00o 开头,如 0o755(十进制的 493)。
  • 十六进制:以 0x 开头,如 0xFF(十进制的 255)。
  1. 自动大整数支持
    Ruby 自动处理整数溢出,小整数(Fixnum)和大整数(Bignum)无缝切换:
a = 123           # => 123(Fixnum)
b = 1234567890 * 9876543210  # => 12193263113702179500(Bignum)
  1. 常用方法
方法说明示例
times { |i| }循环指定次数3.times { |i| puts i } 输出 0,1,2
even?, odd?判断奇偶4.even? => true
to_s(base)转换为字符串(指定进制)255.to_s(16) => "ff"
abs绝对值-5.abs => 5

浮点数(Float)
5. 表示方式

  • 常规写法:3.14, -0.001
  • 科学计数法:6.022e23(6.022 × 10²³)。
  1. 精度问题与解决方案
    浮点数计算可能因精度丢失导致误差:
0.1 + 0.2  # => 0.30000000000000004(并非精确的 0.3)

解决方案

  • 使用 Rational 类型
    (Rational(1, 10) + Rational(2, 10)).to_f  # => 0.3
    
  • BigDecimal(高精度计算):
    require 'bigdecimal'
    a = BigDecimal("0.1")
    b = BigDecimal("0.2")
    a + b  # => 0.3e0
    

数值运算

  1. 基本运算符
运算符说明示例
+加法5 + 3 => 8
-减法5 - 3 => 2
*乘法5 * 3 => 15
/除法5 / 2 => 2(整数除法)
5.to_f / 2 => 2.5
%取模5 % 2 => 1
**幂运算2 ** 3 => 8
  1. 除法行为
  • 整数除法:结果自动向下取整。
    7 / 3    # => 2
    
  • 浮点除法:强制转换为浮点数。
    7.to_f / 3  # => 2.333...
    7 / 3.0     # => 2.333...
    
  1. 链式比较
    Ruby 支持数学中的链式比较:
1 < 2 < 3     # => true
5 <= x <= 10  # 判断 x 是否在 5 到 10 之间

类型转换

目标类型方法示例
整数转浮点to_f5.to_f => 5.0
浮点转整数to_i(截断)3.9.to_i => 3
四舍五入round3.6.round => 4
向上取整ceil3.2.ceil => 4
向下取整floor3.9.floor => 3
字符串转数值to_i, to_f"42".to_i => 42

实用技巧

  1. 随机数生成
rand(10)        # 生成 0~9 的随机整数
rand(5.0..10.0) # 生成 5.0 到 10.0 的随机浮点数
  1. 数值格式化
sprintf("%.2f", 3.1415)  # => "3.14"
3.1415.round(2)          # => 3.14(四舍五入保留两位小数)
  1. 数值范围检查
(1..100).cover?(50)  # => true(检查数值是否在范围内)
  1. 字符串(String)
    单引号(不转义)或双引号(支持转义和插值)。

    str1 = 'Hello \n World'  # 输出换行符
    str2 = "Hello #{name}"   # 插值:Hello Alice
    
  2. 符号(Symbol)
    轻量级字符串,以 : 开头,常用于哈希键。

    :user_id
    
  3. 数组(Array)
    有序集合,通过索引访问。

    nums = [1, 2, 3]
    nums[0]  # => 1
    
  4. 哈希(Hash)
    键值对集合,键可以是任意对象。

    person = { name: "Alice", age: 20 }
    person[:name]  # => "Alice"
    
  5. 范围(Range)
    表示连续区间,常用于迭代。

    (1..5).each { |n| puts n }  # 1到5
    (1...5).each { |n| puts n } # 1到4
    

三、运算符

  1. 算术运算符
    +, -, *, /, %, **(幂运算)。

    2 ** 3  # => 8
    10 % 3  # => 1
    
  2. 比较运算符
    ==, !=, >, <, >=, <=, <=>(返回 -1, 0, 1)。

    5 <=> 3  # => 1(5 > 3)
    
  3. 逻辑运算符
    &&, ||, !(也可用 and, or, not,但优先级不同)。

    true && false  # => false
    
  4. 赋值运算符
    =, +=, -=, *=, /=, %=

    x = 5
    x += 3  # => 8
    

四、控制结构

  1. 条件判断

    # if/elsif/else
    if age >= 18
      puts "Adult"
    elsif age > 0
      puts "Child"
    else
      puts "Invalid"
    end
    
    # 三元运算符
    result = (score > 60) ? "Pass" : "Fail"
    
  2. 循环

    # while 循环
    i = 0
    while i < 3
      puts i
      i += 1
    end
    
    # until 循环
    until i >= 3
      puts i
      i += 1
    end
    
    # for 循环(较少使用)
    for num in [1, 2, 3]
      puts num
    end
    
  3. 迭代器

    # each 方法
    (1..3).each { |n| puts n }
    
    # map 方法
    doubled = [1, 2, 3].map { |n| n * 2 }  # => [2, 4, 6]
    

五、方法定义

  1. 基本语法

    def greet(name)
      "Hello, #{name}!"
    end
    greet("Ruby")  # => "Hello, Ruby!"
    
  2. 默认参数

    def add(a, b = 1)
      a + b
    end
    add(3)    # => 4
    add(3, 5) # => 8
    
  3. 可变参数

    def sum(*nums)
      nums.sum
    end
    sum(1, 2, 3)  # => 6
    

六、异常处理

begin
  # 可能出错的代码
  result = 10 / 0
rescue ZeroDivisionError => e
  puts "Error: #{e.message}"
ensure
  puts "Cleanup code here"
end

七、注释

  1. 单行注释

    # 这是一个注释
    
  2. 多行注释

    =begin
    这是一个多行注释
    可以写多行内容
    =end
    

八、特殊语法

  1. % 符号快捷语法

    %w[apple banana cherry]  # => ["apple", "banana", "cherry"](字符串数组)
    %i[red green blue]       # => [:red, :green, :blue](符号数组)
    
  2. 并行赋值

    a, b = 1, 2  # a=1, b=2
    a, b = b, a   # 交换值:a=2, b=1
    

九、代码块(Block)

  1. 使用 {}do...end

    # 单行用 {}
    [1, 2, 3].each { |n| puts n }
    
    # 多行用 do...end
    [1, 2, 3].each do |n|
      puts "Number: #{n}"
    end
    
  2. 自定义接受块的方法

    def repeat(times)
      times.times { yield }  # yield 调用块
    end
    
    repeat(3) { puts "Hello!" }  # 输出 3 次 Hello
    

十、常用方法示例

  1. 字符串操作

    "ruby".upcase      # => "RUBY"
    "HELLO".downcase   # => "hello"
    "  test  ".strip   # => "test"
    
  2. 数组操作

    [1, 2, 3].include?(2)  # => true
    [1, 2, 3].push(4)      # => [1, 2, 3, 4]
    [1, 2, 3].join("-")    # => "1-2-3"
    

十一、ruby保留关键词

以下是 Ruby 的 全部关键字列表(基于 Ruby 3.x 版本),这些单词具有特殊语法含义,不可用作变量名或方法名:

控制流

关键字说明
if条件判断
else条件分支
elsif多条件分支
unless反向条件判断
case多条件匹配
whencase 语句的分支条件
then简化条件语法
end结束代码块

循环与迭代

关键字说明
while条件循环
until反向条件循环
for遍历循环(较少使用)
in用于 forcase
do定义循环/块的开始
break跳出循环
next跳过当前迭代
redo重新执行当前迭代
retry重新开始循环(已废弃)

类与模块

关键字说明
class定义类
module定义模块
def定义方法
undef取消方法定义
alias方法别名
super调用父类方法
self当前对象

异常处理

关键字说明
begin异常处理块开始
rescue捕获异常
ensure确保执行(类似 finally)
raise抛出异常
throw抛出符号(与 catch 配合)
catch捕获符号

访问控制

关键字说明
public公开方法
private私有方法
protected受保护方法

逻辑与运算符

关键字说明
and逻辑与(低优先级)
or逻辑或(低优先级)
not逻辑非
true布尔真值
false布尔假值
nil空值

其他核心关键字

关键字说明
return从方法返回值
yield调用块
__FILE__当前文件名(伪变量)
__LINE__当前行号(伪变量)
BEGIN程序启动前执行的代码块
END程序退出前执行的代码块
defined?检查标识符是否已定义

模式匹配(Ruby 2.7+)

关键字说明
in模式匹配分支

注意

  1. 非关键字但需谨慎使用
    putsgets 等是全局方法,而非关键字。
    proclambda 是类或方法,可被覆盖(但强烈建议不要这样做)。

  2. 版本差异
    retry 在循环中已废弃(但仍可用于 begin/rescue 块)。
    in 在 Ruby 2.7+ 中用于模式匹配。


完整列表(按字母排序):
__FILE__, __LINE__, BEGIN, END, alias, and, begin, break, case, catch, class, def, defined?, do, else, elsif, end, ensure, false, for, if, in, module, next, nil, not, or, redo, rescue, retry, return, self, super, then, true, undef, unless, until, when, while, yield


总结

Ruby 语法以简洁灵活著称,核心特点是:

  • 无分号,代码块通过缩进或 end 结束。
  • 动态类型,无需声明变量类型。
  • 一切皆对象,方法调用可链式操作。

建议通过实际编码练习巩固语法,例如尝试编写小型脚本或使用 Ruby Playground 在线工具。

— END —

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7.9 升级内核,安装RTX5880驱动

系统镜像下载 https://vault.centos.org/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso 系统安装步骤省略 开始安装显卡驱动 远程登录查看内核 [root192 ~]# uname -a Linux 192.168.119.166 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x8…

Xdocreport实现根据模板导出word

只使用freemaker生成简单的word文档很容易&#xff0c;但是当word文档需要插入动态图片&#xff0c;带循环数据&#xff0c;且含有富文本时解决起来相对比较复杂&#xff0c;但是使用Xdocreport可以轻易解决。 Xdocreport既可以实现文档填充也可以实现文档转换&#xff0c;此处…

当当平台商品详情接口设计与调用指南

当当平台商品详情接口设计与调用指南 接口名称 GET /api/product/detail 图书商品核心信息查询接口 请求参数说明 参数名称 类型 是否必填 说明 isbn string 是 国际标准书号(支持13位/10位) product_id string 否 平台内部商品编号&#xff08;与…

sql server分析表大小

使用自动存储过程查询 EXEC sp_spaceused YourTableName; rows&#xff1a;表中的行数。reserved&#xff1a;表占用的总空间&#xff08;包括数据和索引&#xff09;。data&#xff1a;表数据占用的空间。index_size&#xff1a;索引占用的空间。unused&#xff1a;未使用的空…

《AI大模型应知应会100篇》第13篇:大模型评测标准:如何判断一个模型的优劣

第13篇&#xff1a;大模型评测标准&#xff1a;如何判断一个模型的优劣 摘要 近年来&#xff0c;大语言模型&#xff08;LLMs&#xff09;在自然语言处理、代码生成、多模态任务等领域取得了显著进展。然而&#xff0c;随着模型数量和规模的增长&#xff0c;如何科学评估这些模…

【区块链安全 | 第三十七篇】合约审计之获取私有数据(一)

文章目录 私有数据访问私有数据实例存储槽Solidity 中的数据存储方式1. storage(持久化存储)定长数组变长数组2. memory(临时内存)3. calldata可见性关键字私有数据存储风险安全措施私有数据 私有数据(Private Data)通常指的是只对特定主体可见或可访问的数据,在区块链…

项目管理(高软56)

系列文章目录 项目管理 文章目录 系列文章目录前言一、进度管理二、配置管理三、质量四、风险管理五、真题总结 前言 本节主要讲项目管理知识&#xff0c;这些知识听的有点意思啊。对于技术人想创业&#xff0c;单干的都很有必要听听。 一、进度管理 二、配置管理 三、质量 四…

OpenCV边缘检测方法详解

文章目录 引言一、边缘检测基础概念边缘类型 二、OpenCV中的边缘检测方法1. Sobel算子2. Scharr算子3. Laplacian算子4. Canny边缘检测 三、性能比较与选择建议四、总结 引言 边缘检测是计算机视觉和图像处理中的基础技术&#xff0c;它能有效识别图像中物体的边界&#xff0c…

Linux:shell运行原理+权限

1.shell的运行原理 如果我们打开了命令终端或者是xshell进行远程登录服务器&#xff0c;就会看到命令行&#xff0c;如下图所示&#xff1a; 这个命令行本身也是系统中一个运行起来的程序&#xff0c;它用来接收用户的输入&#xff0c;帮用户来执行指令&#xff0c;将运行结果展…

【LeetCode Solutions】LeetCode 160 ~ 165 题解

CONTENTS LeetCode 160. 相交链表&#xff08;简单&#xff09;LeetCode 162. 寻找峰值&#xff08;中等&#xff09;LeetCode 164. 最大间距&#xff08;中等&#xff09;LeetCode 165. 比较版本号&#xff08;中等&#xff09; LeetCode 160. 相交链表&#xff08;简单&#…

Openssl升级至openssl9.8p1含全部踩坑内容

1、安装依赖包基础条件 yum install gcc yum install gcc-c yum install perl yum install perl-IPC-Cmd yum install pam yum install pam-devel sudo yum install perl-Data-Dumper 问题一&#xff1a;提示yum不可用 镜像源问题更换阿里源即可 wget -O /etc/yum.repos.d/…

二战蓝桥杯所感

&#x1f334; 前言 今天是2025年4月12日&#xff0c;第十六届蓝桥杯结束&#xff0c;作为二战的老手&#xff0c;心中还是颇有不甘的。一方面&#xff0c;今年的题目比去年简单很多&#xff0c;另一方面我感觉并没有把能拿的分都拿到手&#xff0c;这是我觉得最遗憾的地方。不…

查看手机在线状态,保障设备安全运行

手机作为人们日常生活中不可或缺的工具&#xff0c;承载着沟通、工作、娱乐等多种功能。保障手机设备的安全运行是我们每个人都非常重要的任务&#xff0c;而了解手机的在线状态则是其中的一环。通过挖数据平台提供的在线查询工具&#xff0c;我们可以方便快捷地查询手机号的在…

#关于数据库中的时间存储

✅ 一、是否根据“机器当前时区”得到本地时间再转 UTC&#xff1f; 结论&#xff1a;是的&#xff0c;但仅对 TIMESTAMP 字段生效。 数据库&#xff08;如 MySQL&#xff09;在插入 TIMESTAMP 类型数据时&#xff1a; 使用当前会话的时区&#xff08;默认跟随系统时区&#…

第16届蓝桥杯省赛python B组个人题解

文章目录 前言ABCDEFGH 前言 仅个人回忆&#xff0c;不保证正确性 貌似都是典题&#xff0c;针对python的长代码模拟题也没有&#xff0c;一小时速通了&#xff0c;希望不要翻车。 更新&#xff1a;B、G翻车了。。 A 答案&#xff1a;103 B 应该是按长度排序&#xff0c;然后…

lvs+keepalived+dns高可用

1.配置dns相关服务 1.1修改ip地址主机名 dns-master: hostnamectl hostname lvs-master nmcli c modify ens160 ipv4.method manual ipv4.addresses 10.10.10.107/24 ipv4.gateway 10.10.10.2 ipv4.dns 223.5.5.5 connection.autoconnect yes nmcli c up ens160dns-salve: h…

Spark RDD相关概念

Spark运行架构与核心组件 1.Spark运行梁构 spark运行架构包括master和slave两个主要部分。master负责管理整个集群的作业任务调度&#xff0c;而slave则负责实际执行任务。 dirver是Spark驱动器节点&#xff0c;负责执行Spark任务中的main方法&#xff0c;将用户程序转换成作业…

SD + Contronet,扩散模型V1.5+约束条件后续优化:保存Canny边缘图,便于视觉理解——stable diffusion项目学习笔记

目录 前言 背景与需求 代码改进方案 运行过程&#xff1a; 1、Run​编辑 2、过程&#xff1a; 3、过程时间线&#xff1a; 4、最终效果展示&#xff1a; 总结与展望 前言 机器学习缺点之一&#xff1a;即不可解释性。最近&#xff0c;我在使用stable diffusion v1.5 Co…

【ROS2】行为树:BehaviorTree

1、简介 与状态机不同,行为树强调执行动作,而不是状态之间的转换。 行为树是可组合的。可以重复使用简单的行为来构建复杂的行为。 在游戏领域,行为树已经比较流行了。主要用于维护游戏角色的各种动作和状态。 ROS2的导航框架Navigation2中引入了行为树来组织机器人的工作流…

《JVM考古现场(十八):造化玉碟·用字节码重写因果律的九种方法》

"鸿蒙初判&#xff01;当前因果链突破十一维屏障——全体码农修士注意&#xff0c;《JVM考古现场&#xff08;十八&#xff09;》即将渡劫飞升&#xff01;" 目录 上卷阴阳交缠 第一章&#xff1a;混沌初开——JVM因果律的量子纠缠 第二章&#xff1a;诛仙剑阵改—…