# 可見性 [![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/syntax/20_visibility.md%26commit_hash%3De959b3e54bfa8cee4929743b0193a129e7525c61)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/syntax/20_visibility.md&commit_hash=e959b3e54bfa8cee4929743b0193a129e7525c61) Erg 變量具有 __visibility__ 的概念 到目前為止,我們看到的所有變量都稱為 __private variables__。這是一個外部不可見的變量 例如,`foo` 模塊中定義的私有變量不能被另一個模塊引用 ```python # foo.er x = "this is an invisible variable" ``` ```python,compile_fail # bar.er foo = import "foo" foo.x # AttributeError: 模塊 'foo' 沒有屬性 'x' ('x' 是私有的) ``` 另一方面,也有__public variables__,可以從外部引用 公共變量用`.`定義 ```python # foo.er .x = "this is a visible variable" ``` ```python # bar.er foo = import "foo" assert foo.x == "this is a visible variable" ``` 您不需要向私有變量添加任何內容,但您也可以添加 `::` 或 `self::`(用于類型等的`Self::`)以表明它們是私有的。增加。如果它是一個模塊,它也可以是 `module::` ```python ::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. ```python ::x = "this is a private variable" y = x + 1 # 完全是 module::x ``` 通過使用`::`,可以區分作用域內同名的變量 在左側指定要引用的變量的范圍。為頂層指定 `module` 如果未指定,則照常引用最里面的變量 ```python ::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` 指定了它自己的作用域 ```python x = 0 f = x -> log module::x, self::x f1# 0 1 ``` `::` 還負責訪問私有實例屬性 ```python x = 0 C = Class {x = Int} C. # 頂級 x 被引用(警告使用 module::x) f1 self = x # 實例屬性 x 被引用 f2 self = self::x ``` ## 外部模塊中的可見性 在一個模塊中定義的類實際上可以定義來自外部模塊的方法 ```python,compile_fail # foo.er .Foo = Class() ``` ```python # bar.er {Foo;} = import "foo" Foo:: private self = pass Foo. public self = self::private() .f() = foo = Foo.new() foo.public() foo::private() # 屬性錯誤 ``` 但是,這兩種方法都只在該模塊中可用 外部定義的私有方法對 Foo 類的方法僅在定義模塊內可見 公共方法暴露在類之外,但不在模塊之外 ```python # baz.er {Foo;} = import "foo" foo = Foo.new() foo.public() # 屬性錯誤: "Foo"沒有屬性"public"("public"在模塊"bar"中定義) ``` 此外,方法不能在要重新導出的類型中定義 這是為了避免混淆方法是否找到,具體取決于導入方法的模塊 ```python,compile_fail # bar.er {.Foo;} = import "foo" .Foo:: private self = pass # 錯誤 Foo. public self = self::private() # 錯誤 ``` 如果你想做這樣的事情,定義一個 [patch](./type/07_patch.md) ```python # bar.er {Foo;} = import "foo" FooImpl = Patch Foo FooImpl :=: private self = pass Foo Impl. public self = self::private() ``` ```python # baz.er {Foo;} = import "foo" {FooImpl;} = import "bar" foo = Foo.new() foo.public() ``` ## 受限公共變量 可變可見性不限于完全公共/私有 您也可以有限制地發布 ```python,checker_ignore # 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 ``` ```python,checker_ignore foo = import "foo" _ = foo.record.a.x # 可見性錯誤 _ = foo.record.a.y # 可見性錯誤 _ = foo.record.a.z # OK ```

上一頁 | 下一頁