.. _diff_from_original: ******************************************* 与 Squirrel 语言的区别 ******************************************* .. index:: single: diff_from_original 自 2006 年以来,所有 Gaijin 项目中都大量使用Squirrel。 Gaijin 之前使用过 Lua,但发现 Lua 太不安全且难以调试,而且由于缺少类型,有时也很难与原生代码绑定。 这是众所周知的,互联网上有很多关于这方面的信息。 Squirrel 不仅具有类似 C++ 的语法(有时对 C++ 程序员有帮助),而且具有更接近 C:\C++ 代码的类型系统。 它还具有更安全的语法和语义。 然而,在大量使用过程中,我们发现语言的某些功能并未在我们 10+ 平台、20+ 项目中数百万个 LoC 的真实代码库中使用。 一些语言功能也不是很安全,或者不一致。我们需要更严格的语言和工具,以便更轻松地重构和支持。 当然,在游戏开发中,任何额外的性能总是受欢迎的。 基本上,毫无疑问,我们使用了“Python 的 Zen”。 我们将 language 从 Squirrel 重命名为 Quirrel 以避免歧义。 ------------ 新功能 ------------ * 检查冲突的局部变量、局部函数、函数参数和常量名称 * 检查是否存在冲突的 slot 声明 * Null 传播、Null 调用和 Null 合并运算符 * 'not in'运算法 * 解构赋值 * ES2015 风格的速记表初始化 * 字符串插值 * 现在可以命名表达式中声明的函数 (local foo = function foo() {}) * 命名绑定声明 ('let') * 支持类的 call()/acall() 委托 * 将min(), max(), clamp()全局函数添加到 Base 库 * string默认委托: 添加了.subst(), .replace(), .join(), .split(), .concat()方法 * table默认委托: 添加了 .map(), .each(), .findindex(), .findvalue(), .reduce(), __merge(), .__update() 方法 * 数组默认委托: 添加了 .each(), .findvalue(), .replace()方法 * 在 array.slice() 中支持负索引 * 类方法提示(可以在 nonJIT 模式下提供 LuaJIT 的性能) * 编译器指令,用于更严格且更安全的语言(其中一些可用于测试即将发生或计划的语言更改) * 添加了不使用堆栈推送/弹出的 C API * 变量更改跟踪 * 函数'freeze()'用于实例、表、数组。使对象不可变。可以使用'is_frozen'方法检查 ---------------- 删除的功能 ---------------- * 删除了对逗号运算符的支持(从未使用过,但容易出错,例如 table = {["foo", "bar"] = null} 而不是 [["foo","bar"] = null]) * 删除了 class 和 member 属性(从未在任何实际代码中使用过) * 不允许使用 class::method 语法糖添加表格/类方法(因为应该有一种 -- 最好只是一种 -- 明显的方法可以做到这一点。 * # 删除了单行注释(因为应该有一个 -- 最好只有一个 -- 明显的方法来做到这一点。 * 删除了对 post-initializer 语法的支持(不明确,特别是因为可选的逗号) * 删除了对八进制数的支持(容易出错) ---------------- 变更 ---------------- * 函数和类是本地作用域的 * 引用闭包环境对象('this')是显式的 * 未声明的变量没有回退到全局根表,现在需要使用`::` 运算符 * 常量和枚举现在默认在本地范围 * 'global' 关键字,用于显式声明全局常量和枚举 * 数组/字符串 .find() 默认委托重命名为 .indexof() * getinfos() 已重命名为 getfuncinfos(),现在可以应用于可调用对象(实例、表) * array.append() 可以接受多个参数 * 更改了array.filter()的参数顺序以与其他函数统一 * 类型方法调用的语法(对于表)(table.$rawdelete("rawdelete")将适用于表 {rawdelete=@() null}) * 编译器现在基于 AST,具有一些优化(如 closure 提升)和检查。Analyzer 在同一个 AST 上工作。 * 使用 Python 样式进行扩展 (let Baz = class(Bar) //(而不是 Baz = class extends Bar) * 删除 'delete' 运算符(改用 table.rawdelete() 或 table.$rawdelete())。使用 pragma #forbid-delete-operator #allow-delete-operator 指定的可选行为 * 许多方法从全局命名空间移动到标准库 * 已删除 setroottable()。可以用 2 行代码完成(let root=getroottable(); root.each(@(_, k) root.rawdelete(k)); root.__update(newroot)) * 已删除 setconsttable()。它可以破坏东西。唯一安全的使用它的方法 - 在脚本评估之前设置 const 表(可以对 compilestring() 完成)。 -------------------------------- 未来可能的变化 -------------------------------- 请参阅 RFC 页面