Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.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
为什么Swift不允许在类init中分配给self,而在协议init中不允许分配给self?_Swift_Initialization_Pass By Reference_Pass By Value_Initializer - Fatal编程技术网

为什么Swift不允许在类init中分配给self,而在协议init中不允许分配给self?

为什么Swift不允许在类init中分配给self,而在协议init中不允许分配给self?,swift,initialization,pass-by-reference,pass-by-value,initializer,Swift,Initialization,Pass By Reference,Pass By Value,Initializer,我经常发现自己喜欢如何在structs、enums和protocols的初始值设定项中编写类似self=someValue的内容。当我有一些预定义值或正在克隆现有值时,这非常好 但是,此语法不适用于classes。我也不知道为什么。 如果问题是双重初始化,Swift编译器知道我是否、何时、何地调用指定的super或self初始化器,因此它知道我是否完成了对该实例的初始化。 如果问题是我还没有调用指定的初始值设定项,那么应该可以,因为我只是将此实例作为对另一个实例(2个变量1个指针)的引用。 如果

我经常发现自己喜欢如何在
struct
s、
enum
s和
protocol
s的初始值设定项中编写类似
self=someValue
的内容。当我有一些预定义值或正在克隆现有值时,这非常好

但是,此语法不适用于
class
es。我也不知道为什么。 如果问题是双重初始化,Swift编译器知道我是否、何时、何地调用指定的
super
self
初始化器,因此它知道我是否完成了对该实例的初始化。 如果问题是我还没有调用指定的初始值设定项,那么应该可以,因为我只是将此实例作为对另一个实例(2个变量1个指针)的引用。 如果问题是并发访问可能导致
self
已初始化。。。这是胡说八道,因为我们在初始值设定项中

在所有这些之后,我发现我可以通过一次性使用协议来解决这个问题:

class-MyClass{
让内容:字符串
初始化(内容:字符串){
self.content=内容
}
便利初始化(来自1 other:MyClass){
self=other//无法赋值:“self”是不可变的
}
}
协议MyProto{}
扩展MyClass:MyProto{}
扩展MyProto{
初始(来自2其他:自我){
自我=其他
}
}
让foo=MyClass(内容:“foo”)
print(MyClass(from1:foo))//一开始就不会编译
print(MyClass(from2:foo))//非常好!

那么,为什么这在普通用法中被拒绝,但在协议扩展中被允许呢?

目前看来,这一行为与预期相符

整个问题已在swift论坛上讨论:

上一次在内部讨论中出现这种怪癖时,我们中的一些人的想法是,禁止类完全遵守具有变异需求的协议可能是值得的。如果您仔细想想,这是有一定道理的——似乎很难编写既能对可变值也能对可变引用进行通用操作的代码,因为后者没有值语义:

var x = y
x.mutatingProtocolRequirement()
// did y change too?
然而,讨论有点失败了


如果协议是类约束的,它还能工作吗?@JoshCaswell我刚刚测试了它,但没有。在我看来,这是允许的,因为他们希望对值类型允许这一点,并且没有办法只对值类型允许这一点。讨论在某种程度上与此相关。顺便说一句,“这是胡说八道,因为我们在初始值设定项中,Swift初始值设定项不易受此影响”:不,正如我在那里评论的那样,它不是
init
安全的,它是对
静态
属性的赋值。@JoshCaswell哦。。。我没注意到那细微的差别。你能回答一下吗?