Ruby-使用nil参数支持不同类型的类
在Ruby中,假设我有一个名为Ruby-使用nil参数支持不同类型的类,ruby,Ruby,在Ruby中,假设我有一个名为Song的类。我想知道如何正确地编写初始化,以便它支持两种不同类型的。例如: song = Song.new(:cloud) #=> "CloudStorage class initialized" song.storage_kind #=> CloudStorage song.play #=> "...playing song" song\u full=song.new(来自SomeCloudStorage) song\u preview=so
Song
的类。我想知道如何正确地编写初始化
,以便它支持两种不同类型的。例如:
song = Song.new(:cloud) #=> "CloudStorage class initialized"
song.storage_kind #=> CloudStorage
song.play #=> "...playing song"
song\u full=song.new(来自SomeCloudStorage)
song\u preview=song.new(来自本地存储)
然后说我有一个歌曲类,我总是想分配@time\u stamp
,但是根据是否有云存储
,分配@cloud\u存储
def initialize(cloud_storage = nil, time_stamp = nil, local_storage = nil)
@time_stamp = time_stamp || (Time.now.to_f * 1000).to_i.to_s
@cloud_store_spec = cloud_storage
end
我正在考虑使用nil
,正如我所做的那样,但是代码会知道哪个是cloud\u存储
,哪个是local\u存储
。真的有可能吗
感谢您的帮助吗?首先,使用关键字参数允许您将相关数据传递给初始值设定者(如果您希望将时间戳作为关键字或常规参数,则由您决定): 这将使调用类时更加清楚,允许:
song_full = Song.new(cloud_storage: fromSomeCloudStorage)
song_preview = Song.new(local_storage: fromLocalStorage)
就您的代码如何知道代码是来自云还是本地而言,如果您指的是类的实例,您只需检查是否存在@cloud\u store\u spec
,例如:
def cloud_storage?
@cloud_store_spec.present?
end
然后,您可以从代码中的任何其他位置调用:
song_full = Song.new(cloud_storage: fromSomeCloudStorage)
song_full.cloud_storage? # => true
song_preview = Song.new(local_storage: fromLocalStorage)
song_preview.cloud_storage? # => false
希望这能帮上忙,我对你的理解是正确的:)让我知道你进展如何,或者如果你有任何问题
Ruby 1.9.3的更新 由于Ruby 2.0中引入了关键字参数,因此对于1.9.3,您可以使用选项哈希:
def initialize(options = {}) # again, timestamp can be a separate arg if you'd prefer
@time_stamp = options[:time_stamp] || (Time.now.to_f * 1000).to_i.to_s
@cloud_store_spec = options[:cloud_storage]
end
代码的其余部分将保持不变。如果可以将CloudStorage或LocalStorage视为类:
class LocalStorage
def initialize; p 'LocalStorage class initialized'; end
end
class CloudStorage
def initialize; p 'CloudStorage class initialized'; end
def play; p "...playing song"; end
end
也许你可以考虑硬编码一个哈希,(让时间戳分开):< /P> 例如,您可以调用:
song = Song.new(:cloud) #=> "CloudStorage class initialized"
song.storage_kind #=> CloudStorage
song.play #=> "...playing song"
Sweet-太好了,我从来都不知道分号参数注释。我实际上也在使用一个旧版本的Ruby 1.9.3——假设它在那里受支持。太好了,很高兴它有帮助!关键字args是在2.0 IIRC中引入的-给我两分钟,我会用你在1.9.3中可以使用的方法更新答案:)在更新@userMod2中弹出。让我知道这一切是否都对您有效,如果是的话,请随时接受答案。啊,因此即使在执行
def initialize(options={})
时,我仍然可以执行song\u preview=song.new(local\u storage:fromLocalStorage)
是的-您可以提供一个未包装的哈希作为Ruby中任何方法调用的最终参数,这意味着上面的内容等同于Song.new({local\u storage:fromLocalStorage})
。如果您提供了附加参数,则同样适用-无需包装它们。initialize(storage,time_stamp=nil)
如何使用storage
作为LocalStorage
或CloudStorage
的实例,每个实例都是泛型storage
类的子类?这样,Song
只需知道如何使用存储
,子类就可以完成实际工作。
song = Song.new(:cloud) #=> "CloudStorage class initialized"
song.storage_kind #=> CloudStorage
song.play #=> "...playing song"