Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 协议中的Self在子类中如何解释?_Ios_Swift_Swift Protocols_Associated Types - Fatal编程技术网

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)。