作用域
Circcom 与 C 和 Rust 一样具有静态作用域。然而,我们认为信号和组件必须具有全局作用域,因此它们应该在定义它们模板的顶级块中。
#![allow(unused)] fn main() { pragma circom 2.0.0; template Multiplier2 (N) { //Declaration of signals. signal input in; signal output out; //Statements. out <== in; signal input x; if(N > 0){ signal output out2; out2 <== x; } } component main = Multiplier2(5); }
信号out2必须在顶级块中声明。产生一个编译错误:“out2 is outside the initial scope”。
从 circom 2.1.5 开始,信号和组件现在可以在if块内声明,但前提是在编译时是已知条件。
#![allow(unused)] fn main() { pragma circom 2.1.5; template A(n){ signal input in; signal output outA; var i = 0; if(i < n){ signal out <== 2; i = out; } outA <== i; } component main = A(5); }
在前面的示例中,i < n条件在编译时已知,然后允许声明out信号。如果条件 in < n,在编译时是未知的,我们会输出错误,因为这种情况下的声明是不允许的。
关于可见性,组件c的信号x在声明了c的模板t中也是可见的,使用符号c.x,不允许访问嵌套子组件的信号。例如,如果c是使用另一个组件d构建的,则不能从t访问d的信号。这可以在下面的代码中看到:
#![allow(unused)] fn main() { pragma circom 2.0.0; template d(){ signal output x; x <== 1; } template c(){ signal output out2; out2 <== 2; component comp2 = d(); } template t(){ signal out; component c3 = c(); out <== c3.comp2.x; } component main = t(); }
此代码会产生编译错误,因为我们无法访问组件c3的comp2。
var可以在任何块中定义,并且它的可见性会降低到像 C 或 Rust 中那样的块。