理解函数中的泛型 & 泛型约束 —— 究竟谁才是入口?

继续接上篇,做完 AnyMyCollection 之后,

我又添加了一个扩展来修改 CustomCollection 在特定类型下的行为:

1
2
3
4
5
extension CustomCollection where Element == Int {
func allValues() -> [Element] {
[4, 5, 6]
}
}

ElementInt 时,不管三七二十一,直接返回 [4, 5, 6]

但是,运行是发现了这样的现象:

1
2
3
4
5
let collection = CustomCollection(1, 2, 3)
print(collection.allValues()) // [4, 5, 6]

let any = AnyMyCollection(collection)
print(any.allValues()) // [1, 2, 3]

同一个东西,擦除类型之后就不受 Element == Int 约束了嘛?不是

写了一个最小可复现问题的代码,如下:

1
2
3
4
5
6
7
let collection = CustomCollection(1, 2, 3)

func genericFuntion<C: MyCollection>(_ base: C) {
print(base.allValues()) // [1, 2, 3]
}

genericFuntion(collection)

重新来看这个函数,

base 是一个符合 MyCollection 协议的类型,

从程序的角度看,调用函数的时候,它会去找一个入口,

在这里,入口就应该是让 CustomCollection 符合协议的那个 allValues()

Element == Int 约束则可以理解为,当符合条件时,对 allValues() 进行重写,

这里真正让 CustomCollection 符合 MyCollection 的是不受约束的那个扩展中的方法。

仔细一想,貌似实际操作中貌似不会这样“重写”函数,

而是会对一些特定的类型增加一个特殊的函数,

比如:对于类型是 IntArray 增加求平均值的函数等等。

理解函数中的泛型 & 泛型约束 —— 究竟谁才是入口?

https://liyanan2004.github.io/generic-type-function-entry-point/

作者

LiYanan

发布于

2023-01-16

更新于

2023-01-16

许可协议

评论