什么时候在 Ruby 中使用 Struct 而不是 Hash 更好? [英] When is it better to use a Struct rather than a Hash in Ruby?

查看:39
本文介绍了什么时候在 Ruby 中使用 Struct 而不是 Hash 更好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

# 创建一个以常量命名的结构体Customer = Struct.new(:name, :address) #=>顾客Customer.new("Dave", "123 Main") #=>#<客户姓名=戴夫",地址=123 Main">

这看起来既方便又强大,但是,Hash 做的事情非常相似:

Customer = {:name =>"戴夫", :address =>123 主要"}

在哪些实际情况下我应该更喜欢 Struct(以及为什么),以及在选择一种结构时有哪些注意事项或陷阱?

解决方案

就个人而言,当我想让一段数据表现得像一个数据集合而不是在 Hash<下松散耦合时,我会使用结构体.

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

<预><代码>Video = Struct.new(:title, :video_id, :id) 做def to_shttp://youtube.com/get_video.php?t=#{id}&video_id=#{video_id}&fmt=18"结尾定义为空?@title.nil?和@video_id.nil?和@id.nil?结尾结尾

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

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

#!/usr/bin/env ruby​​ -wKU需要ostruct"模块配置模块_功能def load_config_file(路径)评估 <<-END_CONFIG配置 = OpenStruct.new#{File.read(path)}配置END_CONFIG结尾结尾# configuration_file.rbconfig.db = File.join(ENV['HOME'], '.cool-program.db')config.user = ENV['用户']# 用法:Config = Config.load_config('configuration_file.rb')配置.db # =>/home/ba/.cool-program.db配置用户# =>巴Config.non_existant # =>零

Struct<的区别/code> 和 OpenStructStruct 只响应你设置的属性,OpenStruct 响应任何属性集 - 但那些没有设置值的将返回 Nil

A Ruby Struct allows an instance to be generated with a set of accessors:

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

This looks convenient and powerful, however, a Hash does something pretty similar:

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

What are the real-world situations where I should prefer a Struct (and why), and what are the caveats or pitfalls in choosing one over the other?

解决方案

Personally I use a struct in cases when I want to make a piece of data act like a collection of data instead of loosely coupled under a Hash.

For instance I've made a script that downloads videos from Youtube and in there I've a struct to represent a Video and to test whether all data is in place:


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

Later on in my code I've a loop that goes through all rows in the videos source HTML-page until empty? doesn't return true.

Another example I've seen is James Edward Gray IIs configuration class which uses OpenStruct to easily add configuration variables loaded from an external file:

#!/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

The difference between Struct and OpenStruct is that Struct only responds to the attributes that you've set, OpenStruct responds to any attribute set - but those with no value set will return Nil

这篇关于什么时候在 Ruby 中使用 Struct 而不是 Hash 更好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆