怎么说Swift泛型中的"同类"

mat*_*att 5 generics swift

如果Swift泛型类型约束是协议名称,我可以要求约束到该协议的两种类型是相同的类型.例如:

protocol Flier {}
struct Bird : Flier {}
struct Insect: Flier {}
func flockTwoTogether<T:Flier>(f1:T, f2:T) {}
Run Code Online (Sandbox Code Playgroud)

flockTwoTogether可以使用Bird和Bird或昆虫和昆虫调用该函数,但不能使用Bird和Insect.这是我想要的限制.到现在为止还挺好.

但是,如果我使用类名尝试相同的东西,它不起作用:

class Dog {}
class NoisyDog : Dog {}
class WellBehavedDog: Dog {}
func walkTwoTogether<T:Dog>(d1:T, d2:T) {}
Run Code Online (Sandbox Code Playgroud)

问题是我可以walkTwoTogether用WellBehavedDog和NoisyDog调用.这是我想要防止的.

这里有两个问题:

  • 有没有办法说walkTwoTogether不能用WellBehavedDog和NoisyDog调用?

  • 这是一个错误吗?我问,因为如果我不能使用泛型来说这一点,很难理解为什么通用约束完全是一个类名有用,因为我们可以使用普通函数得到相同的结果.

Nat*_*ook 3

本身不是答案,但也许还有更多数据......问题是当你打电话时:

\n\n
walkTwoTogether(NoisyDog(), WellBehavedDog())\n
Run Code Online (Sandbox Code Playgroud)\n\n

Swift 可以将这两个实例视为Dog(又名,向上转换) \xe2\x80\x94 的实例,我们需要它,这样我们就可以调用A具有A. (我知道你知道这一点。)

\n\n

Swift 不会向上转换为协议,因此唯一的方法是为超类不符合的子类指定协议:

\n\n
protocol Walkable {}\nextension NoisyDog : Walkable {}\nextension WellBehavedDog: Walkable {}\nfunc walkTwoTogether<T: Dog where T: Walkable>(d1:T, d2:T) { }\n\nwalkTwoTogether(NoisyDog(), WellBehavedDog())\n// error: type 'Dog' does not conform to protocol 'Walkable'\n
Run Code Online (Sandbox Code Playgroud)\n\n

错误消息明确显示了 \xe2\x80\x94 发生的情况,调用此版本的唯一方法walkToTogether是将子类实例向上转换为Dog,但Dog不符合Walkable

\n