Struct 是 Ruby 中的内置类,可以快速创建简单的类来将几个属性捆绑在一起——自动生成构造函数、访问器、相等性等。这是一种在不编写完整类的情况下定义轻量级数据类的简洁方式。
Struct 解决的问题
,
()
= x
= y
()
x == other.x && y == other.y
= .new(, )
Struct.new(:x, :y) 生成一个具有构造函数、x 和 y 的 attr_accessors、基于值的相等性、to_s 等的类——消除了简单数据类的样板代码。
Point = Struct.new(:x, :y)
p = Point.new(1, 2)
p.x # 1 — accessor generated
p.y = 5 # setter generated
p == Point.new(1, 5) # true — VALUE-based equality (generated)
p.to_a # [1, 5] — convertible
# Structs can have methods too
Point = Struct.new(:x, :y) do
def distance_from_origin
Math.sqrt(x**2 + y**2)
end
end
Point.new(3, 4).distance_from_origin # 5.0
Struct 提供访问器和基于值的相等性(具有相等属性的两个 struct 相等——对于数据对象很方便),你可以在块中添加自定义方法。
# keyword arguments (clearer for many fields)
Point = Struct.new(:x, :y, keyword_init: true)
Point.new(x: 1, y: 2)
# Data (Ruby 3.2+) — an IMMUTABLE alternative to Struct (for value objects)
Point = Data.define(:x, :y)
p = Point.new(1, 2)
p.x # 1 (read-only — immutable)
p2 = p.with(x: 5) # non-destructive copy with a change
Ruby 3.2 的**Data** 是 Struct 的不可变变体——非常适合不应该改变的值对象。
Struct 是 Ruby 中用于快速创建简单数据类而不需要样板代码的有用特性,所以理解它对编写简洁、整洁的 Ruby 很有价值。
核心好处是消除简单数据保存类所需的重复代码——不用编写具有构造函数、attr_accessors 和相等性的完整类,Struct.new(:x, :y) 在一行中生成所有这些,包括基于值的相等性(具有相等属性的两个 struct 相等,这是你对数据对象所需的,与常规类的引用相等性不同)。
这使 Struct 非常适合轻量级数据结构、值对象、从方法返回分组值,以及简单记录(完整的类会过度设计)——一个实用的生产力工具,使代码保持简洁。
理解 Struct(具有生成的访问器和值相等性的简洁数据类,加上添加自定义方法的能力)、关键字初始化的 struct(对许多字段更清晰)和现代**Data** 类(Ruby 3.2 的不可变替代品,用于不应该改变的值对象)是优雅建模简单数据的宝贵知识。
由于定义小型数据类是常见需求,并且 Struct(和 Data)提供了一种简洁的、习惯用法的方式来做到这一点,具有有用的生成行为(特别是值相等性),所以知道何时选择 Struct/Data 对比完整类是实际相关的 Ruby 知识,反映了编写干净、简洁代码的能力——Ruby 开发者工具包中的有用工具,用于频繁任务,即将相关属性捆绑到轻量级类型中,体现了 Ruby 对简洁性的强调和减少样板代码。