Ruby 技术货: 讲讲 Ruby 中纯数据结构 ( Struct 与 OpenStruct )

lyfi2003 · 发布于 2013年09月28日 · 最后由 flingjie 回复于 2014年03月25日 · 7115 次阅读
121

我们知道在 C 与 C++ 中, 拥有 struct 这种纯粹存储数据类型的写法. 我们叫它 结构体.

而且, 在有的时候, 这种用法非常有用, 例如, 我们要存储一张名片, 最简单的方式就是声明一个 Card 结构体:

// c code
#include <stdio.h>
struct card {                                                                   
  char *name;
  char *addr;
};

int main(){
  struct card c;
  c.name = "xxx";
  printf("card: %s\n", c.name);
  return 0;
};

有人会问, 我用类就可以实现同样的功能了嘛,

# ruby code
class Card                                                                  
  attr_accessor :name, :addr
end 

c = Card.new
c.name = 'yafei lee'
puts c.name

但是, 我们却忽略了很多结构体的功能: 对比, 快速声明, 序列化. 这正是 StructOpenStruct 所带给大家的. 同样的问题, 我分别的用 StructOpenStruct 看下:

# ruby code
# struct
Card = Struct.new(:name, :addr)                                             

c = Card.new
c.name = 'yafei lee'
puts c.name

c2 = Card.new
c2.name = 'yafei lee'
puts c2 == c # true

OpenStruct:

# ruby code
require 'ostruct'                                                                         
Card = OpenStruct

c = Card.new
c.name = 'yafei lee'
puts c.name

c2 = Card.new
c2.name = 'yafei lee'
puts c2.name
puts c2 == c # true

可以看得出, StructOpenStruct 让声明结构体更加简单纯粹, 而不需要声明一个 "冗余" 的类, 加一堆属性. 除此之外, 它俩都可以帮助将 ==, eql? 这些事情做好. 最后还实现了 marshal_dumpmarshal_load, 满足持久化的功能: 什么是Marshal 持久化?

最后, 讲一下它俩之间的区别:

来自 WinDy Blog

共收到 19 条回复
9224

好分享。

681

用 Hash 也不错

9224

#3楼 @sevk hash 不够 oo

4755

不錯,最近也有想Ruby中關於數據結構的問題

1959

上次看哪个gem的源码碰到过,有点印象,可以深入了解下。

781

擦。。。我每次都去写一个不保存的数据库类。。。

1026

非常实用的分享,赞一个。

4982

学习一个,前几天正好遇到过OpenStruct,正好理一下

96

学习了

9224

其实 struct 或者 openstruct 非常适合做 money,address 之类值对象,增加代码可读性。

http://www.sitepoint.com/value-objects-explained-with-ruby/ http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

681

嗯, 确实不错

6281

thx for sharing, 解释的很清楚,学习了。

121

@cym 这两篇质量很高,正好可以配合着看看。

121

#5楼 @Martin91 #10楼 @ghosTM55 #9楼 @caok thx~ @sanivbyfish 这次就知道用什么了,正是你这种场合~

4755

#15楼 @lyfi2003 嗯嗯,感謝!

3469

好文章,头球!!!

96

good job, 多谢分享! c中的Struct比较简单,不支持方法,Struct更像是C++中的struct

96

Struct , OpenStruct, Hash 各自适用场合 Use Struct if 1.you need a data container and fields are fixed and known beforehand (i.e. at time of writing of the code), 2.you need a structured Hash key, 3.you want to quickly define a class with a few fields, 4.you need to detect errors caused by misspelled field names.

Use OpenStruct if 1.the number of fields is fixed at runtime but varies frequently during development time (this is often the case for objects that should hold the result of command line option parsing), 2.you need a mock or a want to quickly have objects at hand which can be filled via usual attribute setters and getters. You might want to replaced with a proper class (or Struct) later — with explicit attribute declarations via attr_accessor and relatives.

Use Hash if 1.the number of fields is unknown at coding time, 2.there is a potentially unlimited number of fields (e.g. when reading key values from a file as is often the case for script based text processing). 原文http://blog.rubybestpractices.com/posts/rklemme/017-Struct.html

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册