可见性

badge

Erg 变量具有 visibility 的概念 到目前为止,我们看到的所有变量都称为 private variables。这是一个外部不可见的变量 例如,foo 模块中定义的私有变量不能被另一个模块引用

# foo.er
x = "this is an invisible variable"
# bar.er
foo = import "foo"
foo.x # AttributeError: 模块 'foo' 没有属性 'x' ('x' 是私有的)

另一方面,也有__public variables__,可以从外部引用 公共变量用.定义

# foo.er
.x = "this is a visible variable"
# bar.er
foo = import "foo"
assert foo.x == "this is a visible variable"

您不需要向私有变量添加任何内容,但您也可以添加 ::self::(用于类型等的Self::)以表明它们是私有的。增加。如果它是一个模块,它也可以是 module::

::x = "this is an invisible variable"
assert ::x == x
assert self ::x == ::x
assert module::x == ::x

In the context of purely sequential execution, private variables are almost synonymous with local variables. It can be referenced from the inner scope.

::x = "this is a private variable"
y =
    x + 1 # 完全是 module::x

通过使用::,可以区分作用域内同名的变量 在左侧指定要引用的变量的范围。为顶层指定 module 如果未指定,则照常引用最里面的变量

::x = 0
assert x == 0
y =
    ::x = 1
    assert x == 1
    z =
        ::x = 2
        assert ::x == 2
        assert z::x == 2
        assert y::x == 1
        assert module::x == 0

在匿名子程序作用域中,self 指定了它自己的作用域

x = 0
f = x ->
    log module::x, self::x
f1# 0 1

:: 还负责访问私有实例属性

x = 0
C = Class {x = Int}
C.
    # 顶级 x 被引用(警告使用 module::x)
    f1 self = x
    # 实例属性 x 被引用
    f2 self = self::x

外部模块中的可见性

在一个模块中定义的类实际上可以定义来自外部模块的方法

# foo.er
.Foo = Class()
# bar.er
{Foo;} = import "foo"

Foo::
    private self = pass
Foo.
    public self = self::private()

.f() =
    foo = Foo.new()
    foo.public()
    foo::private() # 属性错误

但是,这两种方法都只在该模块中可用 外部定义的私有方法对 Foo 类的方法仅在定义模块内可见 公共方法暴露在类之外,但不在模块之外

# baz.er
{Foo;} = import "foo"

foo = Foo.new()
foo.public() # 属性错误: "Foo"没有属性"public"("public"在模块"bar"中定义)

此外,方法不能在要重新导出的类型中定义 这是为了避免混淆方法是否找到,具体取决于导入方法的模块

# bar.er
{.Foo;} = import "foo"

.Foo::
    private self = pass # 错误
Foo.
    public self = self::private() # 错误

如果你想做这样的事情,定义一个 patch

# bar.er
{Foo;} = import "foo"

FooImpl = Patch Foo
FooImpl :=:
    private self = pass
Foo Impl.
    public self = self::private()
# baz.er
{Foo;} = import "foo"
{FooImpl;} = import "bar"

foo = Foo.new()
foo.public()

受限公共变量

可变可见性不限于完全公共/私有 您也可以有限制地发布

# foo.er
.record = {
    .a = {
        .(.record)x = 0
        .(module)y = 0
        .z = 0
    }
    _ = .a.x # OK
    _ = .a.y # OK
    _ = .a.z # OK
}

_ = .record.a.x # 可见性错误
_ = .record.a.y # OK
_ = .record.a.z # OK
foo = import "foo"
_ = foo.record.a.x # 可见性错误
_ = foo.record.a.y # 可见性错误
_ = foo.record.a.z # OK