Ios 协议中的Self在子类中如何解释?
在阅读了一篇关于在协议中使用Ios 协议中的Self在子类中如何解释?,ios,swift,swift-protocols,associated-types,Ios,Swift,Swift Protocols,Associated Types,在阅读了一篇关于在协议中使用Self的文章后,我做了一个实验(见下面的代码)。我认为代码将无法编译,因为根据我的理解,类B要符合Copyable协议,它应该有init(u实例:B),我没有定义它。但代码实际上是有效的 我想知道为什么?谢谢你的解释 1 import Foundation 2 protocol Copyable: class { 3 init(_ instance: Self) 4 } 5 class A: Copyable { 6
Self
的文章后,我做了一个实验(见下面的代码)。我认为代码将无法编译,因为根据我的理解,类B
要符合Copyable
协议,它应该有init(u实例:B)
,我没有定义它。但代码实际上是有效的
我想知道为什么?谢谢你的解释
1 import Foundation
2 protocol Copyable: class {
3 init(_ instance: Self)
4 }
5 class A: Copyable {
6 var x: Int
7
8 init(x: Int) {
9 self.x = x
10 }
11
12 required init(_ instance: A) {
13 self.x = instance.x
14 }
15 }
16 class B: A {
17 var y: Int
18
19 init(x: Int, y: Int) {
20 self.y = y
21 super.init(x: x)
22 }
23
24 required init(_ instance: A) {
25 self.y = 1
26 super.init(instance)
27 }
28 }
29 var a = A(x:1)
30 var b = B(a)
根据文件,在这种情况下,自我将是A,因为A是符合协议的,B只是作为A的子类间接地这样做 因此,当A符合
Copyable
时,您是说A及其所有子类必须具有init(uu实例:A)
在协议声明或协议成员声明中,Self类型指符合协议的最终类型
实际上,您可以通过删除
required init(u实例:A)
init来测试这一点,即使您有init(u实例:B)
,也会得到一个错误,因此,由于A是符合协议的类,您必须有一个init,其中实例
参数是A,根据文档本身,在这种情况下,将是A,因为A是符合协议的类,B只是作为A的子类间接地做它
因此,当A符合Copyable
时,您是说A及其所有子类必须具有init(uu实例:A)
在协议声明或协议成员声明中,Self类型指符合协议的最终类型
实际上,您可以通过删除
required init(\uInstance:A)
init来测试这一点,即使您有init(\uInstance:B)
,您也会得到一个错误,因此既然A是符合协议的类,那么您必须有一个init,其中instance
参数是A,谢谢,@Joakim Danielson。在没有实验的情况下,很难理解文档中“符合协议的最终类型”的确切含义。顺便说一句,我真正想要的是寻找某种方法来为我期望的行为定义一个协议(也就是说,一个类及其所有子类都有自己的init(u)实例)
。所以似乎没有办法做到这一点。@rayx注意,从调用方的角度来看,这与您想要的没有什么不同。如果我有一个T
,它被限制为Copyable
,它的初始化器将显示为init(\u:T)
,即使T
是B@Sweeper我明白你的意思。问题是它不能实现我想要的-我希望每个子类都必须实现它们自己的init(u)实例)
。这就是为什么我说它不够强大的原因。@rayx我不知道你的整个类看起来如何,但有一个选择是跳过超类,然后所有类都需要使用自己的类型符合协议。谢谢@JoakimDanielson。这是一种可能的方法,尽管我采取了另一种方法-我只是放弃了将接口放在协议中。我越是使用协议,我就越意识到它有它自己的局限性。我认为我应该用它来做它擅长的事情,并避免与之对抗(例如,使用Self
和子类)。谢谢,@Joakim Danielson。很难理解“符合协议的最终类型”到底是什么在doc中意味着没有实验。顺便说一句,我真正想要的是寻找某种方法来为我期望的行为定义一个协议(也就是说,一个类及其所有子类都有自己的init(u)实例)
。所以似乎没有办法做到这一点。@rayx注意,从调用方的角度来看,这与您想要的没有什么不同。如果我有一个T
,它被限制为Copyable
,它的初始化器将显示为init(\u:T)
,即使T
是B@Sweeper我明白你的意思。问题是它不能实现我想要的-我希望每个子类都必须实现它们自己的init(u)实例)
。这就是为什么我说它不够强大的原因。@rayx我不知道你的整个类看起来如何,但有一个选择是跳过超类,然后所有类都需要使用自己的类型符合协议。谢谢@JoakimDanielson。这是一种可能的方法,尽管我采取了另一种方法-我只是放弃了将接口放在协议中.我越是使用协议,我就越意识到它有它自己的局限性。我认为我应该用它来做它擅长的事情,并避免与之对抗(例如,使用Self
和subclass)。