Subtype Relationships
Inspect one language lane at a time so line-level text and code deltas stay readable.
Diff Lane
English
0 modified sections0 code block delta0 anchor delta
Diff Lane
中文
1 modified sections0 code block delta0 anchor delta
modified函数类型的子类型关系code
v1.0.5
Section Text
1
仓颉语言中,函数是一等公民,而函数类型亦有子类型关系:给定两个函数类型 `(U1) -> S2` 和 `(U2) -> S1`,如果存在 `(U1) -> S2` 是 `(U2) -> S1`的子类型,当且仅当 `U2` 是 `U1` 的子类型,且 `S2` 是 `S1` 的子类型(注意顺序)。例如下面的代码定义了两个函数 `f : (U1) -> S2` 和 `g : (U2) -> S1`,且 `f` 的类型是 `g` 的类型的子类型。由于 `f` 的类型是 `g` 的子类型,所以代码中使用到 `g` 的地方都可以换为 `f`。2
3
<!-- compile -->4
5
6
对于上面的规则,`S2 <: S1` 部分很好理解:函数调用产生的结果数据会被后续程序使用,函数 `g` 可以产生 `S1` 类型的结果数据,函数 `f` 可以产生 `S2` 类型的结果,而 `g` 产生的结果数据应当能被 `f` 产生的结果数据替代,因此要求 `S2 <: S1`。7
8
对于 `U2 <: U1` 的部分,可以这样理解:在函数调用产生结果前,它本身应当能够被调用,函数调用的实参类型固定不变,同时形参类型要求更宽松时,依然可以被调用,而形参类型要求更严格时可能无法被调用——例如给定上述代码中的定义 `g(U2())` 可以被换为 `f(U2())`,正是因为实参类型 `U2` 的要求更严格于形参类型 `U1`。Code 1 · cangjie
1
open class U1 {}2
class U2 <: U1 {}3
4
open class S1 {}5
class S2 <: S1 {}6
7
8
func f(a: U1): S2 { S2() }9
func g(a: U2): S1 { S1() }10
11
func call1() {12
g(U2()) // OK13
f(U2()) // OK14
}15
16
func h(lam: (U2) -> S1): S1 {17
lam(U2())18
}19
20
func call2() {21
h(g) // OK22
h(f) // OK23
}v1.1.0
Section Text
1
仓颉语言中,函数是一等公民,而函数类型亦有子类型关系:给定两个函数类型 `(U1) -> S2` 和 `(U2) -> S1`,如果存在 `(U1) -> S2` 是 `(U2) -> S1`的子类型,当且仅当 `U2` 是 `U1` 的子类型,且 `S2` 是 `S1` 的子类型(注意顺序)。例如下面的代码定义了两个函数 `f : (U1) -> S2` 和 `g : (U2) -> S1`,且 `f` 的类型是 `g` 的类型的子类型。由于 `f` 的类型是 `g` 的子类型,所以代码中使用到 `g` 的地方都可以换为 `f`。2
3
<!-- compile -->4
5
6
对于上面的规则,`S2 <: S1` 部分很好理解:函数调用产生的结果数据会被后续程序使用,函数 `g` 可以产生 `S1` 类型的结果数据,函数 `f` 可以产生 `S2` 类型的结果,而 `g` 产生的结果数据应当能被 `f` 产生的结果数据替代,因此要求 `S2 <: S1`。7
8
对于 `U2 <: U1` 的部分,可以这样理解:在函数调用产生结果前,它本身应当能够被调用,函数调用的实参类型固定不变,同时形参类型要求更宽松时,依然可以被调用,而形参类型要求更严格时可能无法被调用——例如给定上述代码中的定义 `g(U2())` 可以被换为 `f(U2())`,正是因为实参类型 `U2` 的要求更严格于形参类型 `U1`。Code 1 · cangjie
1
open class U1 {}2
class U2 <: U1 {}3
4
open class S1 {}5
class S2 <: S1 {}6
7
func f(a: U1): S2 { S2() }8
func g(a: U2): S1 { S1() }9
10
func call1() {11
g(U2()) // OK12
f(U2()) // OK13
}14
15
func h(lam: (U2) -> S1): S1 {16
lam(U2())17
}18
19
func call2() {20
h(g) // OK21
h(f) // OK22
}