gpt4 book ai didi

ruby - 理解 ruby​​ 类属性,使用访问器宏和 self

转载 作者:数据小太阳 更新时间:2023-10-29 08:16:02 25 4
gpt4 key购买 nike

所以我用 ruby​​ 创建了一个类:

class User
def initialize
end
end

现在假设我想创建一个带有 getter/setter 的散列属性,我对执行此操作的选项感到困惑。

如果我这样做:

class User
attr_accessor :some_hash
end

但我不希望这个散列永远为零,永远是一个空散列。

我不知道什么时候应该做:

def some_hash
self.some_hash ||= {}
end

并做:

def some_hash
@some_hash ||= {}
end

有什么区别?

如果我不使用 attr_accessor,我必须同时创建读取器和写入器(或 getter/setter):

def some_hash=()
end

def some_hash
end

我希望有人可以清除我创建 some_hash 属性的选项,该属性是一个散列,如果它为空则永远不会返回 nil。

即使用 attr_accessor,手动创建方法,最后何时使用@some_hash 和 self.some_hash

最佳答案

attr_accessor :some_hash定义给定属性的读取器和写入器方法。它等同于:

class User
def some_hash
@some_hash
end

def some_hash=(some_hash)
@some_hash = some_hash
end
end

@some_hash引用对象的实例变量,而 some_hashsome_hash=方法。前者返回变量的值,后者设置它。

成语self.some_hash ||= {}相当于self.some_hash || self.some_hash = {} .

Ruby 中的 bool 运算符 short circuit , 这意味着如果第一个表达式 ( self.some_hash = {} ) 返回真值,则第二个表达式 ( self.some_hash ) 根本不会执行。

方法:

def some_hash
self.some_hash ||= {}
end

实际上是递归的,因为它扩展为 some_hash || self.some_hash = {} .它会一直调用自己,直到出现堆栈溢出。使用第二种形式:

def some_hash
@some_hash ||= {}
end

因为它直接设置实例变量,你不会有递归的问题,也不必调用编写器方法。 some_hash永远无法返回 nil ,因为如果 @some_hashnil ,在方法返回之前,它将被分配一个空散列。

顺便说一句,这也叫lazy initialization , 因为变量是在第一次访问时初始化的,而不是 User 时实例已创建。

关于ruby - 理解 ruby​​ 类属性,使用访问器宏和 self,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9809843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com