重新打开类并添加实例变量

Hap*_*ing 1 crystal-lang

我正在自学Crystal-lang,遇到了我不太了解的文档部分。

是文档页面。

在该页面上,它提供以下代码:

class Person
  @age = 0

  def initialize(@name : String)
  end
end
Run Code Online (Sandbox Code Playgroud)

接下来是以下语句:

这将在每个构造函数中将@age初始化为零。这对于避免重复很有用,但在重新打开类并向其添加实例变量时也可以避免使用Nil类型。

有人可以解释一下,还是给我看一个大胆行为的例子?我不确定“重新打开类并向其中添加实例变量”意味着什么。

RX1*_*X14 7

这是重新打开一个类,并向其添加实例变量的示例:

class Person
  @age = 0

  def initialize(@name : String)
  end
end

# Usually in another file

class Person
  def gender=(gender : String)
    @gender = gender
  end

  def gender
    @gender
  end
end

person = Person.new("RX14")

typeof(person.gender) # => String | Nil
person.gender # => nil

person.gender = "???"

person.gender # => "???"
Run Code Online (Sandbox Code Playgroud)

我们添加@gender实例变量,该变量未在中初始化def initialize。编译器会推断@genderbe 的类型String | Nil,因为它被分配给in中的字符串gender=,但未在构造函数中初始化,这意味着它也可以是nil

但是,我们可以向@gender实例变量添加一个默认值,该值适用于所有构造函数,并在默认值之前或之后定义:

class Person
  @age = 0

  def initialize(@name : String)
  end
end

# Usually in another file

class Person
  @gender = "unknown"

  def gender=(gender : String)
    @gender = gender
  end

  def gender
    @gender
  end
end

person = Person.new("RX14")

typeof(person.gender) # => String
person.gender # => "unknown"

person.gender = "???"

person.gender # => "???"
Run Code Online (Sandbox Code Playgroud)

这避免了@gender变量获取String | Nil类型,因为它被初始化为"unknown"when Person构造。由于Nil通常避免使用类型,因此这是一个重要的工具。