变量是一个保存值或对象的名称。 Mojo 中的所有变量都是可变的 - 它们的值可以改变。(如果您想定义一个在运行时无法更改的常量值,请参见 alias 关键字。)

Mojo 曾经支持使用 let 关键字来声明不可变变量。为了简化语言,并出于其他原因,已经将其移除 ( 为何移除let)。为了简化旧代码的迁移,当前仍然支持 let 声明,但其功能与 var 声明相同。

未声明的变量

def函数或REPL环境中,您可以使用变量的名称和值创建一个变量。例如:

  1. name = "Sam"

没有使用 var声明的变量遵循…

fn 函数或结构的字段中,不允许使用未声明的变量。

声明的变量

您可以使用 var 关键字声明一个变量。例如:

  1. var name = "Sam"
  2. var user_id: Int

name变量被初始化为字符串”Sam”。user_id变量未初始化,但它有一个声明的类型,即整数值的Int类型。所有声明的变量都有类型 - 可以是显式地使用类型注解指定的类型,也可以是在使用值初始化时隐式地推断出的类型。

由于声明的变量具有强类型,除非这些类型可以隐式转换,否则不能将变量赋值为不同类型的值。例如,以下代码将无法编译通过:

  1. var user_id: Int = "Sam"

除了类型化,声明的变量还遵循词法作用域,与未声明的变量不同。

最后,使用var有助于防止由拼写错误引起的运行时错误。例如,如果您拼写了一个未声明的变量的名称, Mojo 将简单地使用拼写错误的名称实例化一个新变量。但是,当所有可变变量必须首先用var声明(这是在fn函数内部的情况),那么像下面这样的拼写错误将被编译器捕捉到:

  1. var name = "Sam"
  2. # 以后的某个位置...
  3. nane = "Sammy" # 在`fn`函数中不允许这样做

尽管您可以在def函数中使用var,但只有在fn函数内部使用时才会实现这个好处, Mojo 编译器将会将未声明的变量(例如上面的nane)标记为未知声明。

在REPL环境中使用 Mojo 时,顶层变量(在函数或结构外部的变量)不需要var声明。

类型注解

虽然 Mojo 支持动态变量类型(它可以在运行时推断值的类型),但它也支持对变量进行静态类型注解。这可以为变量提供强大的编译时类型检查,使您的代码更可预测、可管理和安全(特别是与fn函数中的类型检查相结合时)。

要为变量指定类型,请在冒号后面加上类型名称:

  1. var name: String = "Sam"

通过这种方式,name永远不会被赋值为不是字符串的值(或者不能隐式转换为字符串的值)。

您必须使用var声明一个变量才能使用类型注解。

如果一个类型具有只有一个参数的构造函数,您可以以两种方式进行初始化:

  1. var name1: String = "Sam"
  2. var name2 = String("Sam")

这两行代码都使用相同的构造函数从StringLiteral创建一个String

变量

变量是一个保存值或对象的名称。在 Mojo 中,所有的变量都是可变的——它们的值可以被修改。(如果你想定义一个在运行时不能改变的常量值,请参见alias关键字。)

Mojo 以前支持使用let关键字来声明不可变的变量。为了简化语言,并出于其他原因,已经在此处 (opens in a new tab)讨论,并将其移除。为了简化旧代码的迁移,当前仍然支持let声明,但其作用与var声明相同。

未声明的变量

def函数或REPL环境中,您可以仅通过名称和值创建一个变量。例如:

  1. name = "Sam"

没有使用var声明的变量遵循…

fn函数或结构体的字段中,不允许使用未声明的变量。

声明的变量

您可以使用var关键字声明一个变量。例如:

  1. var name = "Sam"
  2. var user_id: Int

name 变量被初始化为字符串 “Sam”。user_id 变量没有被初始化,但它有一个声明的类型,即整数类型 Int。所有声明的值都是有类型的——可以是显式地使用类型注解指定的类型,也可以是在初始化时隐式地推断出的类型。

由于声明的变量是强类型的,除非这些类型可以隐式转换,否则不能将变量赋予不同类型的值。例如,下面的代码将无法编译通过:

  1. var user_id: Int = "Sam"

除了类型化,声明的变量还遵循词法作用域,与未声明的变量不同。

最后,使用var有助于防止由于拼写错误导致的运行时错误。例如,如果您拼写了一个未声明的变量的名称, Mojo 将简单地使用拼写错误的名称实例化一个新变量。但是,当所有可变的变量必须首先使用var声明(这是在fn函数内部的情况),那么像下面这样的拼写错误将被编译器捕获:

  1. var name = "Sam"
  2. # 某个地方以后...
  3. nane = "Sammy" # 这在`fn`函数中是不允许的

虽然您可以在 def 函数中使用 var,但只有在 fn 函数内部使用时才会实现这个好处, Mojo 编译器将会将未声明的变量(比如上面的 nane)标记为未知声明。

在 REPL 环境中使用 Mojo 时,顶层变量(在函数或结构体之外的变量)不需要 var 声明。

类型注解

尽管 Mojo 支持动态变量类型(它可以在运行时推断值的类型),但它也支持对变量进行静态类型注解。这可以为变量提供强大的编译时类型检查,使您的代码更可预测、可管理和安全(特别是与fn函数中的类型检查结合使用时)。

要为一个变量指定类型,请在冒号后面加上类型名称:

  1. var name: String = "Sam"

这样,name将永远不能被赋予一个不是字符串的值(或者不能隐式转换为字符串的值)。

您必须使用var声明一个变量才能使用类型注解。

如果一个类型具有一个只有一个参数的构造函数,您可以使用两种方式进行初始化:

  1. var name1: String = "Sam"
  2. var name2 = String("Sam")

这两行代码都使用相同的构造函数从 `StringLiteral