lcg*_*ida 25
来自Struct文档:
Struct是一种使用访问器方法将多个属性捆绑在一起的便捷方式,而无需编写显式类.
Struct类生成包含一组成员及其值的新子类.对于每个成员,创建类似于Module#attr_accessor的reader和writer方法.
所以,如果我想要一个Person
可以访问name属性(读写)的类,我可以通过声明一个类来实现:
class Person
attr_accessor :name
def initalize(name)
@name = name
end
end
Run Code Online (Sandbox Code Playgroud)
或使用Struct:
Person = Struct.new(:name)
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我都可以运行以下代码:
person = Person.new
person.name = "Name"
#or Person.new("Name")
puts person.name
Run Code Online (Sandbox Code Playgroud)
何时使用?
正如描述所述,当我们需要一组可访问的属性而不必编写显式类时,我们使用Structs.
例如,我想要一个点变量来保存X和Y值:
point = Struct.new(:x, :y).new(20,30)
point.x #=> 20
Run Code Online (Sandbox Code Playgroud)
更多例子:
要添加到其他答案中,有些事情你不能用 Struct 做,有些事情你可以。
例如,您不能创建没有参数的 Struct:
Bar = Struct.new
=> ArgumentError: wrong number of arguments (given 0, expected 1+)
Bar = Struct.new(:bar)
bar = Bar.new(nil)
bar.class
=> Bar
Run Code Online (Sandbox Code Playgroud)
但是,一个类可以让你这样做:
class Foo; end
foo = Foo.new
foo.class
=> Foo
Run Code Online (Sandbox Code Playgroud)
您不能为 Struct 参数设置默认值:
Bar = Struct.new(bar: 'default')
=> ArgumentError: unknown keyword: bar
Bar = Struct.new(bar = 'default')
=> NameError: identifier default needs to be constant
Run Code Online (Sandbox Code Playgroud)
但是你可以用一个类来做,要么传递一个散列,要么参数可以按任何顺序排列,甚至丢失:
class Bar
attr_reader :bar, :rab
def initialize(bar: 'default', rab:)
@bar = bar
@rab = rab
end
end
bar = Bar.new(rab: 'mandatory')
bar.rab
=> 'mandatory'
bar.bar
=> 'default'
bar = Bar.new(rab: 'mandatory', bar: 'custom_value')
bar.rab
=> 'mandatory'
bar.bar
=> 'custom_value'
Run Code Online (Sandbox Code Playgroud)
或者直接传递值,如果参数应该以相同的顺序给出,默认的总是在最后:
class Bar
attr_reader :rab, :bar
def initialize(rab, bar = 'default')
@rab = rab
@bar = bar
end
end
bar = Bar.new('mandatory')
bar.rab
=> 'mandatory'
bar.bar
=> 'default'
bar = Bar.new('mandatory', 'custom_value')
bar.rab
=> 'mandatory'
bar.bar
=> 'custom_value'
Run Code Online (Sandbox Code Playgroud)
你不能用 Structs 做任何事情,除非你以这种超级冗长的方式为你的参数设置默认值:
A = Struct.new(:a, :b, :c) do
def initialize(a:, b: 2, c: 3)
super(a, b, c)
end
end
Run Code Online (Sandbox Code Playgroud)
(示例取自这个答案)
您可以在 Struct 中定义方法:
Foo = Struct.new(:foo) do
def method(argument)
# do something with argument
end
end
end
Run Code Online (Sandbox Code Playgroud)
结构对于创建数据对象很有用,就像其中一个答案中提到的点示例一样。
我有时会使用它们以简单的方式在测试中创建假货和模拟。有时 RSpecallow(foo).to receive(:blah)
等会变得有点冗长,使用 Struct 非常简单。
小智 5
Struct 是用于创建类的 Ruby 简写。在适用的情况下使用 Struct 可以简化您的代码。在https://www.rubytapas.com/2012/11/07/episode-020-struct/ 上有一个很好的讨论
归档时间: |
|
查看次数: |
10403 次 |
最近记录: |