mojo中所有的变量都是可编辑的,所以mojo语言使用alias(后文详述)的方式来定义类似于其他语言中的常量的。
mojo中的变量有两种定义方式,一种是显式指定类型,另一种是定义时不指定类型。
var a:Int = 1;
var b = 0.9;
这两种定义方式都是强类型的,因为mojo编译器会自动推断变量的类型。
甚至可以不用 var 关键字就定义一个变量。
fn main():
diff = String("diff")
延迟初始化
跟其他很多语言类似,一个变量可以先定义,在后续的逻辑中再赋值,这种叫做“延迟初始化”。
未赋初值的变量,是不能出现在等号右侧的,也不能作为实参传递给别的函数。
通过编译阶段的拦截处理了类似于Java中的null的问题。
一个变量如果没有赋初值,那必须得指定类型。
如果不指定类型,编译器就会报错,因为编译器没有办法在一开始就知道这个变量的类型。
隐式类型转换
有一些类型的变量之间是可以进行隐式类型转化的。
例如定义了一个Float类型的变量,可以赋值一个整型的数字。
fn main():
var count:Float32 = 99;
print(count)
## 99.0
因为Float32这个类型在定义是声明了多种重载的构造函数。
我们同样可以在函数参数传递的过程中,使用隐式类型转化。比如一个函数的参数是一个Float32类型的变量,那我们可以传入一个Int类型的值。
变量作用域
凡是用 var 关键字声明的变量都有自己的词法作用域,这个跟大多数语言一样。在函数或者一个代码块内部定义的变量,外部的代码既不能读也不能写。
def lexical_scopes():
var num = 1
var dig = 1
if num == 1:
print("num:", num) # Reads the outer-scope "num"
var num = 2 # Creates new inner-scope "num"
print("num:", num) # Reads the inner-scope "num"
dig = 2 # Updates the outer-scope "dig"
print("num:", num) # Reads the outer-scope "num"
print("dig:", dig) # Reads the outer-scope "dig"
lexical_scopes()
num: 1
num: 2
num: 1
dig: 2
从官网给出的例子看,内部变量的作用域是从声明的地方开始的,声明之前读取的还是外部变量,这一点跟 js 是不同的。
凡是不以 var 关键字开始的变量,都是默认函数级的作用域。也就是说即使在if 内部修改这个变量,在整个函数里都生效。
def function_scopes():
num = 1
if num == 1:
print(num) # Reads the function-scope "num"
num = 2 # Updates the function-scope variable
print(num) # Reads the function-scope "num"
print(num) # Reads the function-scope "num"
function_scopes()
1
2
2