You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通用访问Crystal类中的任意实例变量?

Crystal类实例变量的通用访问方案

1. 用内置宏快速生成getter

Crystal自带getter和property宏,能一键生成实例变量的访问方法,完全不用手动写重复代码:

class Coordinate
  getter x : Int32, y : Int32 # 自动生成x()和y()只读访问方法

  def initialize(x : Int32, y : Int32)
    @x = x
    @y = y
  end
end

coord = Coordinate.new(10, 20)
puts coord.x # 输出10
puts coord.y # 输出20

如果需要同时生成读写方法,把getter换成property就行,这是处理大量变量最高效的方式。

2. 实现动态访问的通用get方法

如果确实需要像你设想的get(var)这种动态访问逻辑,可以用Crystal的反射API instance_variable_get:

class Coordinate
  def initialize(x : Int32, y : Int32)
    @x = x
    @y = y
  end

  def get(var : String)
    instance_variable_get("@#{var}".to_sym)
  end
end

coord = Coordinate.new(10, 20)
puts coord.get("x") # 输出10
puts coord.get("y") # 输出20

注意:反射会带来一定运行时性能开销,编译型语言里尽量按需使用;另外要确保传入的变量名真实存在,否则会抛出NameError,可以根据需求加错误捕获逻辑。

3. 基于宏实现编译期动态访问

如果想避免运行时反射开销,还可以用Crystal的宏在编译阶段处理访问逻辑:

class Coordinate
  @x : Int32
  @y : Int32

  def initialize(x : Int32, y : Int32)
    @x = x
    @y = y
  end

  macro get(var)
    @{{var.id}}
  end
end

coord = Coordinate.new(10, 20)
puts coord.get(x) # 输出10,这里x是编译期已知的符号,不是字符串
puts coord.get(y) # 输出20

这个宏在编译时会直接把get(x)替换成@x,完全没有运行时额外开销,但调用时必须传入编译期就能确定的变量名,不能用运行时生成的字符串。

内容的提问来源于stack exchange,提问作者T. Feix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:18:15