跳转到内容

OpenSCAD 用户手册/面向 C/Java/Python 程序员

来自维基教科书,开放世界中的开放书籍

OpenSCAD 是一种纯函数式语言。这意味着与您可能习惯的编程风格不同。

本文档旨在帮助学习 OpenSCAD 的程序员(他们认为是)“正常”编程语言的程序员,避免过度沮丧。不要以为您是编程专家就可以跳过它。事实上,您对过程式或面向对象语言越熟悉,本文档对您越有帮助。

命令式和过程式与声明式和函数式

[编辑 | 编辑源代码]

一种对编程语言进行分类的方法是区分命令式语言和声明式语言。众所周知的命令式语言包括 C、C++、C#、Java、Python、Ruby、PHP 和 JavaScript。这些语言也可以称为过程式或面向对象语言。所有过程式和面向对象语言都是命令式语言。

命令式程序由一系列改变程序状态的操作组成。例如,语句

x = 5;

在大多数命令式语言中将 x 的值改变为 5。

x = square_root(x);

将 x 的值(从 5)改变为 5 的平方根。

命令式程序具有控制流 - 首先是这一行,然后是下一行,直到某些结构(例如 if、for、while 或函数调用)改变控制流。

另一方面,声明式语言缺乏这些属性。声明式语言包括 HTML、正则表达式、电子表格、Prolog 和纯函数式语言。声明式语言不经历状态变化(html 代码只是存在 - HTML 中没有赋值)。声明式语言就像一个复杂而正式的描述。

声明式语言的一种子类型是“纯函数式”。这意味着用相同的参数调用同一个函数始终返回相同的结果。为了保证这一点,函数内不能进行全局变量或输出的读写。

OpenSCAD 是一种声明式、纯函数式语言。这对许多习惯于命令式语言的程序员来说是一个困惑的来源。他们试图在 OpenSCAD 中做一些“简单的事情”(比如 x = x + 1),但由于一些意想不到的原因,“它无法工作”,无论他们投入多少专业知识都无济于事。为了避免过度沮丧,请阅读本文档的其余部分。

参见

纯函数式语言的优势

[编辑 | 编辑源代码]
  • 程序更可预测,因此不易出错
  • 更容易推理程序,并证明它们是正确的
  • 更容易并行化
  • 由于高级语言和简洁的语法,程序更短
  • 特别是在 OpenSCAD 对布尔运算的建模方式中,保证了布尔 CSG 运算的数学属性(如并集的交换性)

所以现在您知道 OpenSCAD 的设计之所以如此,是因为它具有一定的优势。当您遇到看似过度严格的限制,阻止您进行任何操作时,请牢记这一点。

两种赋值类型

[编辑 | 编辑源代码]

C 和 OpenSCAD 都使用 = 符号进行赋值。两种语言在“赋值”的确切含义上有所不同。C 样式的 = 称为“破坏性更新运算符”,表示“将 .. 设置为”(如将 myvar 设置为 7)。该运算符称为破坏性运算符,因为它会破坏之前保存在变量中的值。它被称为“更新”,因为它将变量的值从旧值更新为新值。

OpenSCAD 样式的赋值表示“是”。它不是破坏性的 - 您无法用新值覆盖旧值。没有旧值和新值,如果 x 是 5,则 x 在整个范围内都是 5,即使在定义它之前也是如此。这更接近于变量和等号的数学定义。

因此,在 OpenSCAD 中不允许重新赋值(破坏性更新)变量。并且没有直接的替代方法。这意味着问题必须以完全不同的方式解决,使用以下技术

  • 不同的变量名称
  • 函数和递归(使用三元运算符 ? : 代替 if)
  • 列表推导和 concat() 函数
// C
cube(x); // undefined behavior - x not yet initialized
x = 4;
cube(x); // call a function to create cube of size 4
x = 5; // destructively update x to 5, in the process destroying the old value.
cube(x); // call a function to create cube of size 5
x++; // set x to x+1. The increment operators in C are also destructive update operators.
cube(x); // call a function to create cube of size 6
// OpenSCAD
y = x + 1; // y is 6
cube(x);  // declare a cube of size 5
x = 5; // x is 5.
cube(x)  // declare a cube of size 5
cube(y)  // declare a cube of size 6
// The other lines are left out, because reassignment of variables are not permitted.

不幸的是,重新赋值目前不会给出错误消息,因为它用于在命令行上指定覆盖。

参见

华夏公益教科书