据我对self
的了解,它指的是该类的当前实例。
这不是始终都是默认行为吗?例如,不是
self.var_one = method(args)
相当于
var_one = method(args)
如果是,self
的用途是什么?
在大多数情况下,self.foo
确实是多余的,因为您可以只写foo
以达到相同的效果,但是在这种情况下则不是,并且需要self
。
[var_one = method(args)
将创建一个名为var_one
的局部变量,它将不会调用任何方法或对self
进行任何其他操作。
[self.var_one = method(args)
将使用参数var_one=
调用self
上的方法method(args)
。
另一种不可选使用self
的情况是,如果您想将其作为方法的参数,即some_method(self)
传递,没有self
关键字就无法这样做。
有几个重要的用途,其中大部分基本上是用于区分实例方法,类方法和变量。
首先,这是定义类方法的最佳方法:
class Foo
def self.bar
"class method bar"
end
def bar
"instance method bar"
end
end
Foo.bar #returns "class method bar"
foo = Foo.new
foo.bar #returns "instance method bar"
此外,在实例方法中,self
引用实例,在类方法中,它引用类,并且始终可以用来与局部变量区分开。
class Bar
def self.foo
"foo!"
end
def baz
"baz!"
end
def self.success
foo #looks for variable foo, doesn't find one, looks for class method foo, finds it, returns "foo!"
end
def self.fail
baz #looks for variable baz, doesn't find one, looks for class method baz, doesn't find one, raises exception
end
def instance_success
baz #looks for variable baz, doesn't find one, looks for instance method baz, finds it, returns "baz!"
end
def instance_fail
foo #looks for variable foo, doesn't find one, looks for instance method foo, doesn't find one, raises exception
end
def local_variable
baz = "is my favorite method"
baz #looks for variable baz, finds it, returns "is my favorite method"
end
def disambiguate
baz = " is my favorite method"
self.baz + baz #looks for instance method baz, finds it, looks for local variable baz, finds it, returns "baz! is my favorite method"
end
end
因此,最后,在许多情况下都可以避免使用self
,但是使用它来确保以后再也不会无意间产生命名冲突通常是有帮助的。有时,这些错误可能会导致很难发现的错误。最后,这通常是个人风格的问题。
如评论中所述,还有一件非常重要的事情:
在类中,如果您有这样的方法:
def bar=(string)
...
end
然后用另一种方法调用:
def other_method
bar = "abcd"
end
不会调用您的bar=
方法,它将创建一个局部变量bar
。因此,在这种情况下,您可以使用self
告诉Ruby不要创建本地变量:
def other_method
self.bar = "abcd"
end
如果要使用方法名称作为参数,则同样适用:
def example
...
end
def other_thing(example)
self.example(example)
end
如果您不使用self
,Ruby将假定您的意思是具有相同名称的局部变量。
因此,通常,方法名称中的self
用于区分类变量和实例变量,当Ruby需要帮助区分方法调用和局部变量或局部变量赋值时,在其他地方都可以使用它。
我希望这是有道理的。
self
的另一种用法是声明类方法(类似于Java中的静态方法。)>
class foo def self.bar #do class related stuff here end end
话虽这么说,您也可以使用
def foo.bar
代替方法签名。
这里是一个例子: