Swift 5.7引入了主关联类型。在试验这个特性时,我想知道是否仍然有像AnySequence这样的类型擦除类型的用例,或者主关联类型是否使这些类型完全过时?
例如,如果我们有以下代码:
protocol Car<Fuel> {
associatedtype Fuel
func drive(fuel: Fuel)
}
struct Electricity {}
struct Petrol {}
struct SportsCar: Car {
func drive(fuel: Petrol) { print("🏎️") }
}
struct FamilyCar: Car {
func drive(fuel: Electricity) { print("🚗") }
}
struct WorkCar: Car {
func drive(fuel: Electricity) { print("🚙") }
}
我们现在可以只使用电动汽车来制作一个数组:
let electricCars: [any Car<Electricity>] = [FamilyCar(), WorkCar()]
以前我会写这样的东西:
struct AnyCar<Fuel>: Car {
//Implementation
}
let electricCars: = [AnyCar(FamilyCar()), AnyCar(WorkCar())]
是否仍有自定义结构“AnyCar”有意义的情况?
谢谢你!
3条答案
按热度按时间aij0ehis1#
虽然主关联类型确实有助于消除使用某些存在类型的许多边缘,但仍然存在使用具体
Any…
类型进行手动类型擦除的用例。存在类型动态地将它们的接口声明的方法分派到底层值,但关键的是,它们自己不能:
1.符合方案
1.实施方法
1.满足静态类型要求
一个非常常见的例子是
Equatable
一致性。我们可以更新Car
协议以采用Equatable
一致性,以指示Car
s应该能够被等同:但是,如果知道两个
Car
的 static 类型,则可以检查它们是否相等,但不能检查两个any Car
值是否相等:Equatable
具有Self
的要求,而any Car
无法满足;但是,如果您编写自己AnyCar
类型,则可以做到这一点:使用这个 Package 器,您可以检查两个任意的
AnyCar
值是否相等:这种方法在使用
AnyHashable
作为字典的通用键类型时可能看起来很熟悉,字典可以包含任何类型的键。你不能用any Hashable
实现同样的功能:与
AnyCar
相反,AnyHashable
的好处是如此普遍和必要,以至于编译器会自动 PackageAnyHashable
中的类型,这样你就不需要自己做了,使它在很大程度上不可见。hgb9j2n62#
存在(
any
)类型不符合它们的协议,所以any Car<Electric>
本身不是Car。考虑一个只能容纳特定类型汽车的车库:
创建一个
Garage<FamilyCar>
是合法的:但是创建
Garage<any Car>
是不合法的:但是,在这种情况下,您可以构建AnyCar来处理它。
Garage<AnyCar>
有效,即使Garage<any Car>
无效。这种情况不应该经常出现,通常应该尽可能避免使用
any
(尽可能首选some
)。any
类型现在比早期版本的Swift中的强大得多,你应该更喜欢它们而不是显式类型擦除。但是,仍然有角落的情况下,他们失败了。在Swift的未来版本中,
any
类型可能会符合某些协议(特别是那些没有static
或init
要求的协议,这是主要的症结所在)。但我们还没到那一步。有关未来发展方向的详细信息,请参阅:any
(And各种各样的东西从他们内部联系起来。里面有很多东西)。
7xzttuei3#
问题是类型擦除是一个概念,这意味着我们不应该将对象的确切实现细节传递给用户。
这个概念是通过创建
AnyCar
自定义类型来使用的。但是随着
any
关键字的引入,我们仍然使用相同的概念,只是方式不同。如果代码使用
any <Protocol>
变得“太复杂”,我们仍然可以使用自定义结构类型