在类定义中,这两种方法有什么区别?
def func(var)
...
end
def func=(var)
...
end
有没有,或者其中一个无效?
答案 0 :(得分:6)
它们都是有效的方法定义。但第二个是定义一个“定位器”。方法 - 您可以使用以下语法调用此方法:
obj.func = 123
本声明将翻译成
obj.func=(123)
您可以查看this answer,我会更详细地解释这种语法。
答案 1 :(得分:2)
在Ruby中解释有关读者/作者AKA getter / setter方法的一些内容:
Ruby并没有强迫我们在setter的方法定义中使用=
。我们可以选择该方法是否有一个。
考虑一下:
class Foo
# automagically creates:
# .v
# .v=
attr_accessor :v
def initialize(v)
puts "inside initialize(#{ v })"
@v = v
end
def setter(v)
puts "inside setter(#{ v })"
@v = v
end
def setter=(v)
puts "inside setter=(#{ v })"
@v = v
end
end
f = Foo.new(1)
puts f.v
f.setter(2)
puts f.v
f.setter = 3
puts f.v
f.setter=(4)
puts f.v
f.v = 5
puts f.v
f.v=(6)
puts f.v
运行代码输出:
inside initialize(1)
1
inside setter(2)
2
inside setter=(3)
3
inside setter=(4)
4
5
6
=
只是方法名称中的另一个字母,因为Ruby足够聪明,知道它是否应该f.setter = 3
使用setter=(v)
方法。
Ruby不会强制使用=
来设置变量,您可以在定义方法时决定它是否对您更有意义。我们使用=
是惯用的,因为它有助于使setter看起来像一个赋值,消除了将所有setter命名为set_v(v)
的冲动。
答案 2 :(得分:1)
如果您愿意,可以定义getter
和setter
方法。假设您有一个带有电话属性的Person
课程。
class Person
def phone
@phone
end
def phone=(number)
@phone = number
end
end
现在,您只需设置将调用@phone
方法的属性即可更改手机属性(在phone=
内部管理)。
john = Person.new
john.phone = "123-456-7890"
它看起来像是外面的财产分配。您可以在方法名称末尾堆叠的其他字符对于布尔getter为?
,对于破坏性操作为!
。同样,这些只是约定,你可以随意使用这三个字符。但是,使用这些符号代码看起来更自然。例如,
question.closed?
document.destroy!