裝飾器

badge

裝飾器用于向類型或函數添加或演示特定狀態或行為 裝飾器的語法如下

@deco
X = ...

你可以有多個裝飾器,只要它們不沖突

裝飾器不是一個特殊的對象,它只是一個單參數函數。裝飾器等價于下面的偽代碼

X = ...
X = deco(X)

Erg 不允許重新分配變量,因此上面的代碼不起作用 對于簡單的變量,它與X = deco(...)相同,但對于即時塊和子例程,你不能這樣做,所以你需要一個裝飾器

@deco
f x =
    y = ...
    x + y

# 還可以防止代碼變成水平的
@LongNameDeco1
@LongNameDeco2
C = Class ...

下面是一些常用的內置裝飾器

可繼承

指示定義類型是可繼承的類。如果為參數 scope 指定 "public",甚至可以繼承外部模塊的類。默認情況下它是"private",不能被外部繼承

最后

使該方法不可覆蓋。將它添加到類中使其成為不可繼承的類,但由于它是默認值,因此沒有意義

覆蓋

覆蓋屬性時使用。默認情況下,如果您嘗試定義與基類相同的屬性,Erg將拋出錯誤

實現

表示參數trait已實現

Add = Trait {
    .`_+_` = Self.(Self) -> Self
}
Sub = Trait {
    .`_-_` = Self.(Self) -> Self
}

C = Class({i = Int}, Impl := Add and Sub)
C.
    @Impl Add
    `_+_` self, other = C.new {i = self::i + other::i}
    @Impl Sub
    `_-_` self, other = C.new {i = self::i - other::}

指定默認情況下隨trait附帶的附件補丁 這允許您重現與Rust Trait相同的行為

# foo.er
Add R = Trait {
    .AddO = Type
    .`_+_` = Self.(R) -> Self.AddO
}
@Attach AddForInt, AddForOdd
ClosedAdd = Subsume Add(Self)

AddForInt = Patch(Int, Impl := ClosedAdd)
AddForInt.AddO = Int
AddForOdd = Patch(Odd, Impl := ClosedAdd)
AddForOdd.AddO = Even

當從其他模塊導入Trait時,這將自動應用附件補丁

# 本來應該同時導入IntIsBinAdd和OddIsBinAdd,但是如果是附件補丁可以省略
{BinAdd;} = import "foo"

assert Int. AddO == Int
assert Odd.AddO == Even

在內部,它只是使用trait的.attach方法附加的。可以使用trait的.detach方法消除沖突

@Attach X
T = Trait ...
assert X in T. attaches
U = T.detach(X).attach(Y)
assert X not in U. attaches
assert Y in U. attaches

已棄用

指示變量規范已過時且不推薦使用

測試

表示這是一個測試子例程。測試子程序使用erg test命令運行