類型轉換

badge

向上轉換

因為 Python 是一種使用鴨子類型的語言,所以沒有強制轉換的概念。沒有必要向上轉換,本質上也沒有向下轉換 但是,Erg 是靜態類型的,因此有時必須進行強制轉換 一個簡單的例子是 1 + 2.0: +(Int, Ratio) 或 Int(<: Add(Ratio, Ratio)) 操作在 Erg 語言規范中沒有定義。這是因為 Int <: Ratio,所以 1 向上轉換為 1.0,即 Ratio 的一個實例

~~ Erg擴展字節碼在BINARY_ADD中增加了類型信息,此時類型信息為Ratio-Ratio。在這種情況下,BINARY_ADD 指令執行 Int 的轉換,因此沒有插入指定轉換的特殊指令。因此,例如,即使您在子類中重寫了某個方法,如果您將父類指定為類型,則會執行類型強制,并在父類的方法中執行該方法(在編譯時執行名稱修改以引用父母的方法)。編譯器只執行類型強制驗證和名稱修改。運行時不強制轉換對象(當前。可以實現強制轉換指令以優化執行)。~~

@Inheritable
Parent = Class()
Parent.
    greet!() = print! "Hello from Parent"

Child = Inherit Parent
Child.
    # Override 需要 Override 裝飾器
    @Override
    greet!() = print! "Hello from Child"

greet! p: Parent = p.greet!()

parent = Parent.new()
child = Child.new()

parent # 來自Parent的問候!
child #  來自child的問候!

此行為不會造成與 Python 的不兼容。首先,Python 沒有指定變量的類型,所以可以這么說,所有的變量都是類型變量。由于類型變量會選擇它們可以適應的最小類型,因此如果您沒有在 Erg 中指定類型,則可以實現與 Python 中相同的行為

@Inheritable
Parent = Class()
Parent.
    greet!() = print! "Hello from Parent"

Child = Inherit Parent
Child.
    greet!() = print! "Hello from Child" Child.

greet! some = some.greet!()

parent = Parent.new()
child = Child.new()

parent # 來自Parent的問候!
child  # 來自child的問候!

您還可以使用 .from.into,它們會為相互繼承的類型自動實現

assert 1 == 1.0
assert Ratio.from(1) == 1.0
assert 1.into<Ratio>() == 1.0

向下轉換

由于向下轉換通常是不安全的并且轉換方法很重要,我們改為實現TryFrom.try_from

IntTryFromFloat = Patch Int
IntTryFromFloat.
    try_from r: Float =
        if r.ceil() == r:
            then: r.ceil()
            else: Error "conversion failed".