類型擦除
類型擦除是將類型參數設置為 _
并故意丟棄其信息的過程。類型擦除是許多多態語言的特性,但在 Erg 的語法上下文中,將其稱為類型參數擦除更為準確
類型擦除的最常見示例是 [T, _]
。數組在編譯時并不總是知道它們的長度。例如,引用命令行參數的 sys.argv
的類型為 [Str, _]
。由于 Erg 的編譯器無法知道命令行參數的長度,因此必須放棄有關其長度的信息
然而,一個已經被類型擦除的類型變成了一個未被擦除的類型的父類型(例如[T; N] <: [T; _]
),所以它可以接受更多的對象
類型的對象[T; N]
當然可以使用 [T; _]
,但使用后會刪除N
信息。如果長度沒有改變,那么可以使用[T; N]
在簽名中。如果長度保持不變,則必須由簽名指示
# 保證不改變數組長度的函數(例如,排序)
f: [T; N] -> [T; N] # 沒有的函數 (f: [T; N])
# 沒有的功能(例如過濾器)
g: [T; n] -> [T; _]
如果您在類型規范本身中使用 _
,則類型將向上轉換為 Object
對于非類型類型參數(Int、Bool 等),帶有 _
的參數將是未定義的
i: _ # i: Object
[_; _] == [Object; _] == Array
類型擦除與省略類型說明不同。一旦類型參數信息被刪除,除非您再次聲明它,否則它不會被返回
implicit = (1..5).iter().map(i -> i * 2).to_arr()
explicit = (1..5).iter().map(i -> i * 2).into(Array(Nat))
在 Rust 中,這對應于以下代碼:
#![allow(unused)] fn main() { let partial = (1..6).iter().map(|i| i * 2).collect::<Vec<_>>(); }
Erg 不允許部分省略類型,而是使用高階種類多態性
# collect 是采用 Kind 的高階 Kind 方法
hk = (1..5).iter().map(i -> i * 2).collect(Array)
hk: Array(Int)