在Ruby中有一种方法来重载初始化构造函数?
在Java中,你可以重载构造函数:
public Person(String name) { this.name = name; } public Person(String firstName, String lastName) { this(firstName + " " + lastName); }
有没有办法在Ruby中实现相同的结果:两个构造函数采取不同的参数?
答案是“是”和“否”
您可以使用多种机制获得与其他语言相同的结果,包括: –
- 参数的默认值
- variables参数列表(图示操作符)
- 将您的参数定义为散列
即使参数不同,语言的实际语法也不允许您定义两次方法。
考虑到以上三个选项,这些可以用你的例子来实现,如下所示
# As written by @Justice class Person def initialize(name, lastName = nil) name = name + " " + lastName unless lastName.nil? @name = name end end class Person def initialize(args) name = args["name"] + " " + args["lastName"] unless args["lastName"].nil? @name = name end end class Person def initialize(*args) #Process args (An array) end end
您将在Ruby代码中经常遇到第二种机制,特别是在Rails中,因为它提供了两全其美的function,并且允许一些语法糖来生成漂亮的代码,特别是不需要将传递的散列括在大括号中。
这个wikibooks链接提供了更多的阅读
我倾向于这样做
class Person def self.new_using_both_names(first_name, last_name) self.new([first_name, last_name].join(" ")) end def self.new_using_single_name(single_name) self.new(single_name) end def initialize(name) @name = name end end
但我不知道这是否是最好的方法。
class Person def initialize(name, lastName = nil) name = name + " " + lastName unless lastName.nil? @name = name end end
class StatementItem attr_reader :category, :id, :time, :amount def initialize(item) case item when Order initialize_with_order(item) when Transaction initialize_with_transaction(item) end end def valid? !(@category && @id && @time && @amount).nil? end private def initialize_with_order(order) return nil if order.status != 'completed' @category = 'order' @id = order.id @time = order.updated_at @amount = order.price end def initialize_with_transaction(transaction) @category = transaction.category @id = transaction.id @time = transaction.updated_at @amount = transaction.amount end end
您可以使用konstructor gem在Ruby中声明多个构造函数,并模拟重载:
class Person def initialize(name) @name = name end konstructor def from_two_names(first_name, last_name) @name = first_name + ' ' + last_name end end Person.new('John Doe') Person.from_two_names('John', 'Doe')
我通常做:
class Person attr_reader :name def initialize(first: nil, last: nil) @name = [first, last].compact.join(' ') end end Person.new(first: 'ya').name # => "ya" Person.new(first: 'ya', last: 'ku').name # => "ya ku"