Ruby中实现类C/C++多维括号式Getter/Setter方法(非Hash)
在Ruby中实现类C/C++的多维下标Getter/Setter(不依赖Hash)
当然可以做到!Ruby虽然没有原生支持def [][]=(a, b, value)这种直接语法,但我们可以通过代理模式巧妙实现类似多维下标赋值/取值的效果,完全不需要用Hash来模拟正规表格的接口。
核心思路其实很简单:当你调用a[1]的时候,这个[]方法不直接返回数据,而是返回一个“代理对象”——它持有原实例的引用和第一个下标值;当你接着调用[1] = 2时,代理对象会把两个下标和值一起传递给原实例的内部方法,完成实际的读写操作。
自定义表格类的实现示例
咱们先写一个实用的自定义表格类,底层用二维数组存储数据,但对外暴露干净的多维下标接口:
class Table def initialize(rows = 10, cols = 10, default = 0) @data = Array.new(rows) { Array.new(cols, default) } end # 处理第一个下标,返回代理对象 def [](row_index) RowHandler.new(self, row_index) end # 内部实际赋值逻辑,供代理调用 def assign_value(row, col, value) @data[row][col] = value end # 内部实际取值逻辑,供代理调用 def retrieve_value(row, col) @data[row][col] end # 嵌套的代理类,处理第二个下标 class RowHandler def initialize(table_instance, row) @table = table_instance @row = row end # 处理第二个下标的赋值 def []=(col_index, value) @table.assign_value(@row, col_index, value) end # 处理第二个下标的取值 def [](col_index) @table.retrieve_value(@row, col_index) end end end
使用演示
用起来和你想要的效果完全一致:
# 初始化一个10x10的表格 my_table = Table.new # 多维下标赋值 my_table[1][1] = 2 # 多维下标取值 puts my_table[1][1] # 输出:2
给内置类扩展的例子(以Integer为例)
如果你非要给内置类(比如你提到的Integer)扩展这个功能——虽然Integer是不可变值类型,实际场景中不太推荐这么做——但也可以实现:
class Integer def []=(row, col, value) # 用实例变量存储每个Integer实例的多维数据 @multi_data ||= {} @multi_data[[row, col]] = value end def [](row) MultiIndexProxy.new(self, row) end class MultiIndexProxy def initialize(int_instance, row) @int = int_instance @row = row end def []=(col, value) @int[@row, col] = value end def [](col) @int.instance_variable_get(:@multi_data)&.fetch([@row, col], nil) end end end # 测试 a = 5 a[1][1] = 2 puts a[1][1] # 输出:2
这种实现方式的关键在于,我们并没有把Hash暴露给用户当表格用,而是通过代理对象把两次下标操作“拼接”成了一次对底层数据的读写,完全模拟了C/C++风格的多维变量接口。
内容的提问来源于stack exchange,提问作者von spotz
相关产品推荐
相关产品推荐

