可以像这样定义
Struct.new(:x, :y)
但是可以用它们做些什么呢?具体来说,我如何创建这样的结构的实例?这不起作用
Struct.new(:x => 1, :y => 1)
(获得TypeError: can't convert Hash into String
)。
我正在使用Ruby 1.9.2。
更新:
到目前为止,好的指针,谢谢。我想我之所以这样说的原因是我有几次发现自己想要这样做
Struct.new(:x => 1, :y => 1)
只是为了让我可以在我可以写obj.x
的地方传递一个对象,而不是,例如,实例化一个哈希并且必须写obj[:x]
。在这种情况下,我希望结构真的匿名 - 我不希望通过命名从Struct.new
调用返回的内容来污染我的命名空间。最接近的是,如已经建议的那样
Struct.new(:x, :y).new(1, 1)
但是你觉得苹果怎么样?我不确定。期望能够一次性定义和实例化匿名结构(作为核心Ruby的一部分)是否合理?我想当我在Struct.new
上阅读官方Ruby文档时,我认为“匿名”一词允许这样,但事实并非如此。
答案 0 :(得分:18)
Struct.new
会返回Class
,因此您可以将其分配给这样的常量:
Point = Struct.new(:x, :y)
或将其子类化:
class Point < Struct.new(:x, :y)
# custom methods here
# ...
end
在这两种情况下,您都可以使用结果类:
Point.new(3, 5)
如果您不想创建特定的类(因为您只需要将该类的对象实例化一次),请考虑改为使用OpenStruct
:
require 'ostruct'
point = OpenStruct.new(:x => 3, :y => 5)
答案 1 :(得分:4)
好吧,如果你真的不想写一个带有访问器的类,你可以使用Structs。只写
很方便Project = Struct.new(:name)
而不是
class Project
attr_accesor :name
end
正如tokland正确地指出的那样(谢谢!),一个Struct也会自动为你提供一个很好的#initialize方法。因此,如果没有任何进一步的代码,可以进行以下操作:
Project = Struct.new(:name)
p = Project.new('Quadriloptic Curves')
答案 2 :(得分:3)
首先创建一个结构,然后可以创建它的实例。这是一种无需声明类即可创建数据对象的方法。基本上它与哈希相同,但访问对象更干净。你可以通过普通的访问器方法来引用它。
http://www.ruby-doc.org/core-1.9.3/Struct.html
# Create a structure with a name in Struct
Struct.new("Customer", :name, :address) #=> Struct::Customer
Struct::Customer.new("Dave", "123 Main") #=> #<struct Struct::Customer name="Dave", address="123 Main">
# Create a structure named by its constant
Customer = Struct.new(:name, :address) #=> Customer
Customer.new("Dave", "123 Main") #=> #<struct Customer name="Dave", address="123 Main">
答案 3 :(得分:2)
我很确定目的,但Struct.new
会返回课程
irb(main):001:0> Struct.new(:x,:y)
=> #<Class:0x2914110>
irb(main):002:0> Struct.new(:x,:y).new(1,2)
=> #<struct x=1, y=2>
答案 4 :(得分:1)
OpenStruct
可能就是你想要的,但我最近遇到OpenStruct
无法工作的情况,因为我在尝试访问未定义的属性时需要引发错误。 Struct
确实:
os = OpenStruct.new
os.x = 1; os.y = 2;
os.z # returns nil
s = Struct.new(:x, :y).new
s.x = 1; s.y = 2;
s.z # raises NoMethodError
要记住一些事情。
答案 5 :(得分:0)
至于创建实例:
User = Struct.new(:user,:password)
u = User.new("john","secret")