Ruby中Python Dataclasses的等价实现及简洁类定义方法
Ruby中对应Python Dataclasses的特性是什么?
Ruby没有和Python Dataclasses完全等价的内置特性,但可以通过几种方式实现类似的简洁数据类定义,不用手动重复编写构造方法里的属性赋值逻辑。
先对比Python的用法:
Python 不使用dataclasses的写法
class myNewDog2: def __init__(self, fur_colour: str, weight: float, is_microchipped: bool, is_asleep: bool = False): self.fur_colour = fur_colour self.weight = weight self.is_microchipped = is_microchipped self.is_asleep = is_asleep my_dog = myNewDog2("tri-colour", 19.52, True)
Python 使用dataclasses简化后的写法
from dataclasses import dataclass @dataclass class myDog2: fur_colour: str weight: float is_microchipped: bool is_asleep: bool = False # 可选参数,默认值False my_dog = myDog2("tri-colour", 19.52, True)
Ruby 常规等价写法
class MyDog def initialize(fur_colour:, weight:, is_microchipped:, is_asleep: false) @fur_colour = fur_colour @weight = weight @is_microchipped = is_microchipped @is_asleep = is_asleep end end
下面是几种Ruby的简洁实现方案:
1. 使用内置的Struct
Struct是Ruby内置工具,可快速生成包含指定属性的类,自动生成构造方法和属性访问器。如果需要关键字参数和默认值,写法如下:
MyDog = Struct.new(:fur_colour, :weight, :is_microchipped, :is_asleep, keyword_init: true) do def initialize(fur_colour:, weight:, is_microchipped:, is_asleep: false) super(fur_colour: fur_colour, weight: weight, is_microchipped: is_microchipped, is_asleep: is_asleep) end end # 使用示例 my_dog = MyDog.new(fur_colour: "tri-colour", weight: 19.52, is_microchipped: true) puts my_dog.fur_colour # 输出 "tri-colour"
2. Ruby 3.2+ 用Data类(不可变数据类)
Ruby 3.2引入了Data类,专门用于定义不可变数据类,语法更简洁,自动生成只读访问器和构造方法:
require 'data' class MyDog < Data def initialize(fur_colour:, weight:, is_microchipped:, is_asleep: false) end end # 使用示例 my_dog = MyDog.new(fur_colour: "tri-colour", weight: 19.52, is_microchipped: true) # 注意:Data实例不可修改,执行 my_dog.fur_colour = "black" 会报错
3. 自定义简化逻辑(可变属性)
如果需要可变的实例属性,可以结合attr_accessor和动态赋值减少重复代码:
class MyDog attr_accessor :fur_colour, :weight, :is_microchipped, :is_asleep def initialize(fur_colour:, weight:, is_microchipped:, is_asleep: false) # 自动将参数赋值给对应实例变量 binding.local_variables.each do |var| next if var == :self instance_variable_set("@#{var}", binding.local_variable_get(var)) end end end # 使用示例 my_dog = MyDog.new(fur_colour: "tri-colour", weight: 19.52, is_microchipped: true) my_dog.is_asleep = true # 可以修改属性
这些方案都能实现类似Python Dataclasses的简洁性,不用手动编写重复的属性赋值代码。
内容的提问来源于stack exchange,提问作者MolarFox
相关产品推荐
相关产品推荐

