Skip to content

变量

变量的声明

和其他语言一样,你可以在MCFPP中声明一些变量用来储存、传递、处理数据。

变量的声明一般如下:

mcfpp
#<变量的类型> <变量的标识符> [= 表达式或值]
int i = 5;
int b = i * 6;

变量的标识符可以为任意字母和数字的组合。在同一个作用域中,一个相同名称的变量只能被声明一次。

变量的类型

在MCFPP中,变量分为基本数据类型和复合数据类型。基本数据类型是硬编码且内定的,而复合数据类型,比如类、模板等,则可以由开发者自己确定。目前来说,MCFPP已有的基本类型如下所示:

类型名类型描述例子
int最基础的类型,表示一个整数1,114514,-5
float表示一个单精度浮点数2.5,1.0,9.5e6
bool表示一个布尔型数据true,false
nbt表示一个NBT数据"a":{"b":"c"},"a":[1,2,3,4]
list表示一个列表[1,2,3,4],["a","b","c"]
dict表示一个字典{"a":1,"b":2,"c":3}
map字典的更高级包装,拥有比字典更多的功能同上
string表示一个字符串"mcfpp","qwq"
text表示一个Json原始文本"mcfpp",{"text":"mcfpp","color":"#114514"}
entity表示一个实体。储存了一个实体的UUID
selector表示一个目标选择器@a,@p

以下是对类型的简要介绍,可以逐一展开查看:

int

int类型是MCFPP中最基础的类型,表示一个整数。它可以是正数、负数、零,也可以是十进制、二进制、八进制、十六进制等。一个int类型的数据会被储存为一个记分板变量,因此它的大小和记分板的大小一样。

float

表示MCFPP中的一个浮点数。它的精度和单精度浮点数相当。它可以是正数、负数、零,也可以是十进制、科学计数法等。MCFPP的浮点数运算依赖小豆的数学库完成。浮点数的运算为纯粹的记分板运算,因此占用量不会很大。

bool

表示一个布尔型数据。它只有两个值:truefalse。bool类型的数据会被储存为一个记分板变量,因此它的大小和记分板的大小一样。

nbt

表示一个NBT数据。不过实际上,NBT类型的数据更多情况下只是储存了一个NBT路径,因此把它们称作NBT指针也不足为过。值得注意的是,nbt类型的变量是大多数基本类型的基础,例如listmap等都依托NBT数据的操作实现。

list

表示一个列表。list类型实现了java中ArrayList的大多数方法,详细可以参考标准库的API。list会被储存为一个NBT列表。

dict

表示一个字典,被储存为一个NBT复合标签。受MC的限制,dict类型只能进行基本的键值对插入和删除操作,无法进行遍历操作。你可以使用map来进行更多的操作。

map

dict类型的更高级包装,拥有比dict更多的功能。map类型实现了java中HashMap的大多数方法,详细可以参考标准库的API。但是值得注意的是,map的更高级包装意味着map会拥有比dict更多的开销。

string

表示一个字符串,即NBT中的string标签。

text

表示一个原始JSON文本,相较于string类型,text类型可以包含更多的格式信息,例如颜色、粗体等。text类型的数据会被储存为一个NBT复合标签。

entity

表示单个实体。储存为一个UUID整数型NBT数组。

selector

表示一个目标选择器。储存为一个字符串。

var关键字

var关键字是MCFPP中的一个特殊关键字,它可以用来声明一个变量,而不需要指定变量的类型。编译器会根据变量的初始化表达式来推断变量的类型。

然而,如果要使用var关键字声明一个变量,那么变量的初始化表达式是必须的。

例如:

mcfpp
var i = 5; #i的类型会被推断为int
var j = 5.0; #j的类型会被推断为float
var i; #错误,缺少初始化表达式

变量修饰符

变量修饰符可以用来表示变量的特性,包括dynamicconst

  • dynamic

在编译过程中,如果有变量被声明为字面量,例如int i = 5;,编译器就会对此变量进行优化处理,比如i += 7,会直接在编译器中将i记录为12而非编译为记分板命令。而 dynamic用于表示一个变量无论如何都会是编译时动态计算的,即使它是一个字面量。例如dynamic int i = 5;i在编译时也会被当作一个动态变量,而不会被优化。

  • const

const用于表示一个变量是一个常量,即它的值在编译时就已经确定了,且不会改变。例如const int i = 5;i在编译时就会被当作一个常量。常量总是编译时静态的。常量的值必须在声明时就确定,不能在声明后再赋值。

变量的编译时优化

在编译的过程中,编译器会针对一些编译器已知的量进行优化处理。当一个变量被直接赋值为字面量的时候,编译器就会记住这个变量的名字,直到对这个变量失去跟踪。

mcfpp
int i = 5;  #编译器记住了这个变量的值为5
i += 7;     #编译器直接将i的值记为12,不会输出记分板命令
int j = i;  #编译器同样也知道了j的值

import int x;
j = x;      #编译器丢失了对j具体值的跟踪
j += 1;     #编译器会输出记分板命令