Ruby struct 允许使用一组访问器生成实例:

# Create a structure named by its constant
Customer = Struct.new(:name, :address)     #=> Customer
Customer.new("Dave", "123 Main")           #=> #<Customer name="Dave", address="123 Main">

这看起来既方便又强大,然而,散列的作用非常类似:

Customer = {:name => "Dave", :address => "123 Main"}

在现实世界中,我应该 Select 什么样的 struct (以及为什么),在 Select 其中一种 struct 时有哪些注意事项或trap ?

推荐答案

就我个人而言,当我想让一段数据像一个数据集合一样工作,而不是在Hash下松散耦合时,我会使用struct.

例如,我制作了一个从Youtube下载视频的脚本,其中我有一个 struct 来表示视频,并测试所有数据是否到位:


Video = Struct.new(:title, :video_id, :id) do
  def to_s
    "http://youtube.com/get_video.php?t=#{id}&video_id=#{video_id}&fmt=18"
  end

  def empty?
    @title.nil? and @video_id.nil? and @id.nil?
  end
end

稍后在我的代码中,我有一个循环,它遍历视频源HTML页面中的所有行,直到empty?不返回true.

我看到的另一个例子是James Edward Gray IIs configuration class,它使用OpenStruct轻松添加从外部文件加载的配置变量:

#!/usr/bin/env ruby -wKU

require "ostruct"

module Config
  module_function

  def load_config_file(path)
    eval <<-END_CONFIG
    config = OpenStruct.new
    #{File.read(path)}
    config
    END_CONFIG
  end
end

# configuration_file.rb
config.db = File.join(ENV['HOME'], '.cool-program.db')
config.user = ENV['USER']

# Usage:
Config = Config.load_config('configuration_file.rb')
Config.db   # => /home/ba/.cool-program.db
Config.user # => ba
Config.non_existant # => Nil

如果设置了Struct,则返回的属性之间的差异为OpenStruct,而设置的属性之间的差异为100

Ruby相关问答推荐

R10K模块在try 安装gem r10k时获得错误的Ruby版本

如何修复 '535-5.7.8 用户名和密码未被接受.在 Devise 邮件确认错误中了解更多信息?

Ruby 匹配第一次出现的字符串以进行 gsub 替换

你如何称呼 Ruby 中的 &: 运算符?

`expect`测试中的Rspec`eq`与`eql`

Ruby 中的 :+ 和 &:+ 是什么?

将一个目录的内容复制到另一个目录

如何在两个浮点数之间的范围内最好地创建一个随机浮点数

将方法应用于数组/可枚举中的每个元素

根据另一个数组的元素对数组进行排序

在 Ruby 中创建数字、字符串、数组或哈希的 md5 哈希

Ruby - 在模块/类之间共享记录器实例

Bundle不适用于 rbenv

跳过 Enumerable#collect 中的迭代

如何使用 Nokogiri 删除 node ?

如何计算Ruby日期的星期几?

安装 Jekyll 时出错 - 本机扩展构建

如何判断变量是数字还是字符串?

如何在没有 RVM 的 Ubuntu 上安装 Ruby 2

如何在Ruby中将字符串拆分为仅具有给定字符的两部分?